Попробуйте
SELECT OrderId,
COUNT(*) ItemCount,
SUM(CASE WHEN PriceType = 'CopyCost' THEN Price ELSE 0 END) TotalCopyCost,
SUM(CASE WHEN PriceType = 'FullPrice' THEN Price ELSE 0 END) TotalFullPrice
FROM OrderDetails
GROUP BY OrderId
Single []
- это тесты условий, совместимые с командами, совместимыми с командами.
Двойной [[]]
является расширением стандарта []
и поддерживаются bash и другими оболочками (например, zsh, ksh). Они поддерживают дополнительные операции (а также стандартные операции posix). Например: ||
вместо -o
и соответствия регулярных выражений с =~
. Более полный список различий можно найти в разделе bash manual по условным конструкциям .
Используйте []
, когда вы хотите, чтобы ваш скрипт был переносимым через оболочки. Используйте [[]]
, если вы хотите, чтобы условные выражения не поддерживались []
и не нуждались в переносе.
вы можете использовать двойные квадратные скобки для соответствия регулярному регулярному выражению, например. :
if [[ $1 =~ "foo.*bar" ]] ; then
(если версия bash, которую вы используете, поддерживает этот синтаксис)
Различия в поведении
Протестировано в Bash 4.3.11:
[
- POSIX [[
is расширение Bash [
- это просто регулярная команда со странным именем. ]
- это просто аргумент [
, который не позволяет использовать дополнительные аргументы. Ubuntu 16.04 фактически имеет исполняемый файл для него в /usr/bin/[
, предоставленный coreutils, но встроенная версия bash имеет приоритет. Ничто не изменяется в том, как Bash анализирует команду. В частности, <
является перенаправлением, &&
и ||
объединяют несколько команд, ( )
генерирует подоболочки, если не экранируется \
, и расширение слова происходит, как обычно. [[ X ]]
представляет собой единую конструкцию, которая делает X
разыгранным магическим образом. <
, &&
, ||
и ()
обрабатываются специально, а правила разделения слов различны. Существуют также дополнительные различия, такие как =
и =~
. В Bashese: [
- встроенная команда, а [[
- ключевое слово: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and- shell-keyword <
[[ a < b ]]
: лексикографическое сравнение [ a \< b ]
: То же, что и выше. \
, или же перенаправление, как и для любой другой команды. Расширение Bash. Я не мог найти альтернативу POSIX, см. . Как проверить строки для меньших или равных? &&
и ||
[[ a = a && b = b ]]
: true, logical и [ a = a && b = b ]
: синтаксическая ошибка, &&
проанализирована как разделитель команды AND cmd1 && cmd2
[ a = a -a b = b ]
: эквивалентна, но устарела POSIX [ a = a ] && [ b = b ]
: рекомендация POSIX (
[[ (a = a || a = b) && a = b ]]
: false [ ( a = a ) ]
: синтаксическая ошибка, ()
интерпретируется как подоболочка [ \( a = a -o a = b \) -a a = b ]
: эквивалентна, но ()
устарела с помощью POSIX ([ a = a ] || [ a = b ]) && [ a = b ]
Рекомендация POSIX x='a b'; [[ $x = 'a b' ]]
: true, кавычки не нужны x='a b'; [ $x = 'a b' ]
: синтаксическая ошибка, расширяется до [ a b = 'a b' ]
x='a b'; [ "$x" = 'a b' ]
: эквивалентна =
[[ ab = a? ]]
: true, потому что она соответствует шаблону (* ? [
являются волшебными). Не расширяет glob для файлов в текущем каталоге. [ ab = a? ]
: a?
glob расширяется. Так может быть истинным или ложным в зависимости от файлов в текущем каталоге. [ ab = a\? ]
: false, а не расширение glob =
и ==
одинаковы для обоих [
и [[
, но ==
является расширением Bash. printf 'ab' | grep -Eq 'a.'
: эквивалент POSIX ERE [[ ab =~ 'ab?' ]]
: false, теряет магию с помощью ''
[[ ab? =~ 'ab?' ]]
: true =~
[[ ab =~ ab? ]]
: true, расширенное регулярное выражение POSIX match, ?
не glob expand [ a =~ a ]
: синтаксическая ошибка printf 'ab' | grep -Eq 'ab?'
: эквивалент POSIX Рекомендация
Я предпочитаю всегда использовать []
.
Есть эквиваленты POSIX для каждой конструкции [[ ]]
, которую я видел.
Если вы используете [[ ]]
, вы:
[
- это просто регулярная команда со странным именем, никакая специальная семантика не задействована. []
следует читать как . Мои предпочтения : используйте []
, если вы не хотите потерять переносимость. Как указано здесь : Если переносимость / соответствие POSIX или BourneShell вызывает беспокойство, следует использовать старый синтаксис. Если, с другой стороны, сценарий требует BASH, Zsh или KornShell, новый синтаксис обычно более гибкий, но не обязательно обратно совместимый. I> Я бы предпочел пойти с [[ ab =~ ab? ]]
, если можно, и не беспокоюсь о обратная совместимость, чем printf 'ab' | grep -Eq 'ab?'
– archemiro
23 April 2017 в 15:33
[[
является ключевым словом bash, аналогичным (но более мощным, чем) командой [
.
См.
http://mywiki.wooledge.org/BashFAQ/031 и http://mywiki.wooledge.org/BashGuide / TestsAndConditionals
Если вы не пишете POSIX sh, мы рекомендуем [[
.
Внутри отдельных скобок для теста условий (т. е. [...]) некоторые операторы, такие как single =
, поддерживаются всеми оболочками, тогда как использование оператора ==
не поддерживается некоторыми из старых оболочек.
Внутренние двойные скобки для теста условий (т. е. [[...]]), нет никакой разницы между использованием =
или ==
в старых или новых оболочках.
Изменить : Я должен также отметить, что: В bash всегда используйте двойные скобки [[...]], если это возможно, потому что это безопаснее, чем отдельные скобки. Я проиллюстрирую, почему в следующем примере:
if [ $var == "hello" ]; then
, если $ var оказывается пустым / пустым, то это то, что видит скрипт:
if [ == "hello" ]; then
, который будет сломайте свой скрипт. Решение состоит в том, чтобы либо использовать двойные скобки, либо всегда помнить о том, чтобы помещать кавычки вокруг ваших переменных ("$var"
). Двойные скобки - лучшая защитная практика кодирования.
Руководство Bash говорит:
При использовании с [[, операторы '& lt;' и '>' сортируют лексикографически с использованием текущей локали. Команда test использует порядок ASCII.
(Команда тестирования идентична [])
[[ ]]
(например, bash с#!/bin/bash
или#!/usr/bin/env bash
), вы должны использовать переносную опцию. Сценарии, которые предполагают, что / bin / sh поддерживают такие расширения, будут разбиваться на операционные системы, такие как недавние выпуски Debian и Ubuntu, где это не так. – Gordon Davisson 8 August 2018 в 21:21