SQL(Server)中 NULL 或空字符串仍然存在。

3

I have this query

SELECT Ets_Se_Categorie AS Ets_Se_Categorie,COUNT(Ets_Se_Categorie) AS cpte
FROM TableV_MyTest
GROUP BY Ets_Se_Categorie

它为我提供了以下表格 / 结果。
Ets_Se_Categorie                                            cpte
(Seems to be empty string)                                  5531
Old place                                                   8
Secondary                                                   1066
Principal                                                   4713
Subsidiary                                                  7985
First                                                       9
headquarter                                                 31610
Main Headquarter                                            1587

(似乎是空字符串) 表示该字段为空。

目的是要实现这个:

Ets_Se_Categorie                                            cpte
Old place                                                   8
Secondary                                                   1066
Principal                                                   4713
Subsidiary                                                  7985
First                                                       9
headquarter                                                 31610
Main Headquarter                                            1587

我已经创建了这个查询

 SELECT *
 FROM
 (
 SELECT Ets_Se_Categorie AS Ets_Se_Categorie,COUNT(Ets_Se_Categorie) AS cpte
 FROM TableV_MyTest 
 GROUP BY Ets_Se_Categorie
 ) AS A
 WHERE (A.Ets_Se_Categorie IS NOT NULL OR A.Ets_Se_Categorie != '')

问题在于没有任何变化...
为什么使用了嵌套查询?
我首先尝试了这个:
 SELECT Ets_Se_Categorie,COUNT(Ets_Se_Categorie) AS cpte
 FROM TableV_MyTest 
 WHERE (Ets_Se_Categorie IS NOT NULL OR Ets_Se_Categorie != '')
 GROUP BY Ets_Se_Categorie

什么也没发生……

非常感谢您的任何见解。可能很简单,但我对其中的原因有些困惑。

谢谢!


2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - sgeddes
5
你想要的是那些列不为null且不为''的行(即改为使用AND来得到你想要的结果,而不是OR)。 - Alex K.
2
我刚刚注意到,你在查询attempted时使用了OR而不是AND - Shantanu Gupta
5个回答

3
您使用了OR而不是AND,应该改为如下代码:
WHERE (A.Ets_Se_Categorie IS NOT NULL AND A.Ets_Se_Categorie != '')

由于存在关于为什么 OR 没有按预期工作的困惑:

两个条件都必须为 true 才能返回记录。所有记录都是 NOT NULL 或者 != ''。考虑一个空字符串的记录,这个记录是 NOT NULL,因此它会被返回。

为什么你没有看到 NULL 记录:

NULL 不是有效值,它意味着 未定义。因此,没有东西既相等也不相等于 NULL。既不是 NULL = NULL 也不是 Anything != NULLtrue。您必须使用 IS (NOT) NULL

在您的原始查询中,您已经过滤掉了 NULL 值:

 SELECT Ets_Se_Categorie,COUNT(Ets_Se_Categorie) AS cpte
 FROM TableV_MyTest 
 WHERE (Ets_Se_Categorie IS NOT NULL OR Ets_Se_Categorie != '')
 GROUP BY Ets_Se_Categorie

因为NULL既不是NOT NULL也不是!= ''(请记住上一节),所以结论是:要么使用IS NOT NULL AND != '',要么使用ISNULL(Column, '') != ''COALESCE(Column, '') != '',这是ANSI sql(在所有数据库中都适用)。

@AndyK:因为两个条件都必须为真才能返回此记录。所有记录都是“NOT NULL”或“!= ''”。考虑您有一个“NULL”记录,此记录为“!= ''”,因此它被返回。考虑一个空字符串的记录,此记录为“NOT NULL”,因此它被返回。因此,“OR”引起了您的问题。 - Tim Schmelter
是的,但如果它是NULL就不行。你总是需要两个条件都为真。所以使用AND - Tim Schmelter
我看了你的评论,开始理解了。不过还有一个问题:如果有一个NULL'',为什么计数没有将其视为NULL并将其放在那里?TIA @tim-schmelter - Andy K
@AndyK:”the count did not see it”是什么意思?在你的问题中,空字符串的count值为5531,是吗? - Tim Schmelter
@TimSchmelter 如果是这种情况,那么 Ets_Se_Categorie != '' 应该可以进行排除...或者我错过了什么,因为我太*愚蠢了(d或n:随便选一个 :)) - Andy K
显示剩余7条评论

2
您可以直接使用 ISNULL 函数,如下所示:

WHERE ISNULL(A.Ets_Se_Categorie, '') != ''


该函数可帮助您判断字段是否为空,并在为空时返回默认值。

1
非常优雅!我喜欢它@tom-chantler - Andy K
2
或使用 ANSI SQL 中的 COALESCE(A.Ets_Se_Categorie, '') != '' - Tim Schmelter
是的,蒂姆说得对。虽然这个问题被标记为 Microsoft SQL Server 特定的,但你说的 COALESCE 是 ANSI 的答案。 - Tom Chantler

1
你尝试过使用 LTRIM, RTRIM 去除空格吗?(保留HTML标签)
 SELECT 
    LTRIM(RTRIM(Ets_Se_Categorie))
    ,COUNT(LTRIM(RTRIM(Ets_Se_Categorie))) AS cpte
 FROM TableV_MyTest 
 WHERE 
    (Ets_Se_Categorie IS NOT NULL AND LTRIM(RTRIM(Ets_Se_Categorie)) != '')
 GROUP BY 
       LTRIM(RTRIM(Ets_Se_Categorie))

这只是使查询变慢的原因。LTRIM(RTRIM(Ets_Se_Categorie)) != ''与LTRIM(Ets_Se_Categorie) != ''完全相同,甚至与Ets_Se_Categorie != ''完全相同。例如,比较无空格和有空格的示例返回0行:SELECT 1 WHERE '' != ' '。 - t-clausen.dk

1

尝试检查你的列中的空格。

SELECT Ets_Se_Categorie AS Ets_Se_Categorie,COUNT(Ets_Se_Categorie) AS cpte
FROM TableV_MyTest
WHERE LEN(ISNULL(Ets_Se_Categorie, '')) <> 0
GROUP BY Ets_Se_Categorie

1

你需要在这里使用AND。它仍然返回,因为它查看并发现该列不为NULL并将其返回。这就是OR的工作方式,如果第一个子句为真,则返回。

 SELECT Ets_Se_Categorie,COUNT(Ets_Se_Categorie) AS cpte
 FROM TableV_MyTest 
 WHERE (Ets_Se_Categorie IS NOT NULL AND Ets_Se_Categorie != '')
 GROUP BY Ets_Se_Categorie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接