Булева логика в предложении Select - PullRequest
1 голос
/ 01 июля 2011

Очевидно, я не могу сделать это:

SELECT 
  SUM( t.MyField IS NULL ) AS totalNulls, 
  SUM( t.MyField LIKE '[0-9]') AS totalNumbers
FROM MyTable AS t;

Я не знаю, почему они не работают, поскольку логические значения в SQL - это просто числа (0 и 1). Но ошибки, которые я получаю, указывают на то, что в любом случае в предложении select нельзя указывать «равно нулю» или «как». Почему они там не законны? Как мне достичь желаемого эффекта, как это предлагается в (псевдо) SQL выше?

Ответы [ 5 ]

6 голосов
/ 01 июля 2011

SQL Server понятия не имеет, что такое логическое значение.BIT <> логическое значение, хотя это распространенное заблуждение.Вы также не можете выполнять управление потоком в операторе SELECT (например, IF).В следующей версии SQL Server мы получим встроенную функциональность IIF (), которая делает то, что вы ищете.А пока вам нужно использовать выражение CASE.

SELECT
  totalNulls =   SUM(CASE WHEN t.MyField IS NULL      THEN 1 ELSE 0 END),
  totalNumbers = SUM(CASE WHEN t.MyField LIKE '[0-9]' THEN 1 ELSE 0 END)
FROM MyTable AS t;
1 голос
/ 01 июля 2011

Если ваши данные не проиндексированы в запрашиваемом столбце, вам следует использовать решение на основе CASE, рекомендованное Аароном, поскольку строки будут запрашиваться только один раз.

select  totalNulls = sum(case when MyField is null then 1 else 0 end),
        totalNumbers = sum(case when MyField like '[0-9]' then 1 else 0 end)
from    MyTable;

Вы должны знать, что принимаете только, например, «7» в данном случае не «12». Если вы хотите принять какие-либо номера, вы должны спросить

... when MyField not like '%[^0-9]%' ...

В этом случае вы можете использовать заклинание с помощью числового значения:

select  totalNonNumbers = count(*) - sum(isnumeric(MyField)),
        totalNumbers = sum(isnumeric(MyField))
from    MyTable;

Если столбец проиндексирован, вариант решения Майклса может быть самым быстрым:

select  totalNulls = (select count(*) from MyTable where MyField is null),
        totalNumbers = 
          (select count(*) from MyTable where MyField between '0' and '9');

Есть так много способов ...

1 голос
/ 01 июля 2011

ВЫБЕРИТЕ СУММУ (СЛУЧАЙ, КОГДА t.MyField НУЛЯЕТ ТОЛЬКО 1 ИЛИ 0 КОНЕЦ) как TotalNulls

Я не думаю, что операторы сравнения возвращают 1 и 0, я думаю, что они обрабатываются по-разному, ноЯ не уверен в этом, однако сумма в выражении case будет работать, и вы можете сделать это за один проход на столько столбцов / вычислений, сколько захотите.

0 голосов
/ 01 июля 2011

Еще один способ ...

declare @t table (
  id int null
)
insert into @t
select 1
union
select null
union
select 2

SELECT
  totalNulls =   COUNT(*)-COUNT(ID),
  totalNumbers = SUM(CASE WHEN ISNUMERIC(t.id)=1 THEN 1 ELSE 0 END)
FROM @t AS t;
0 голосов
/ 01 июля 2011

Один из способов будет:

SELECT 
  count(*) AS totalNulls, 
  0 as totalNumbers
FROM MyTable AS t
where t.MyField is null
union 
SELECT 
  0 AS totalNulls, 
  count(t.MyField) AS totalNumbers
FROM MyTable AS t
where t.MyField like '[0-9]';

Первая строка будет содержать нулевое количество, вторая строка будет содержать общее количество t.MyField, содержащее цифры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...