选择子句中的布尔逻辑

时间:2011-06-30 23:17:23

标签: sql-server tsql sql-server-2008

显然,我不能这样做:

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

我不知道为什么这些不起作用,因为SQL中的布尔值只是数字(0和1)。但是我得到的错误表明,在select子句中的任何地方都有'is null'或'like'是不合法的。他们为什么不在那里合法?我如何实现预期的效果,如上面的(伪)SQL所建议的那样?

5 个答案:

答案 0 :(得分:5)

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 :(得分:1)

SELECT SUM(当t.MyField为NULL,然后1 ELSE 0 END)为TotalNulls

我认为比较运算符不会返回1和0,我认为它们的处理方式不同,但我不确定这一点,但是case语句的总和是可行的,你可以一次性完成在你想要的任意数量的列/计算上。

答案 2 :(得分:0)

一种方法是:

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总数。

答案 3 :(得分:0)

如果您的数据未在查询列上编制索引,则应使用Aaron推荐的基于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]%' ...

在这种情况下,你可以使用isnumeric:

来做一个魅力
select  totalNonNumbers = count(*) - sum(isnumeric(MyField)),
        totalNumbers = sum(isnumeric(MyField))
from    MyTable;

如果列被编入索引,Michaels解决方案的变体可能是最快的:

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

有很多方法......

答案 4 :(得分:-1)

还有一种方法......

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;