【发布时间】:2014-12-18 13:02:43
【问题描述】:
当我准备回答我们这里的一位同事时,我遇到了一个奇怪的情况,至少对我来说是这样。原来的问题在这里:Pivot Table Omitting Rows that Have Null values
我已将查询修改为使用max 而不是group_concat,以便在所有数据库中显示“问题”。
SELECT
id,
max(case when colID = 1 then value else '' end) AS fn,
max(case when colID = 2 then value else '' end) AS ln,
max(case when colID = 3 then value else '' end) AS jt
FROM tbl
GROUP BY id
这个查询的结果是这样的:
ID FN LN JT
1 Sampo Kallinen Office Manager
2 Jakko Salovaara Vice President
3 (null) Foo No First Name
用户要求过滤 ID 为 3 的行,因为字段 value 为空。
当它看起来很明显时,只需在该查询上添加WHERE value IS NOT NULL 约束即可实现用户期望。它不会工作。
所以我开始在其他数据库上对其进行测试,看看会发生什么(使用 WHERE CLAUSE 进行查询)
SELECT
id,
max(case when colID = 1 then value else '' end) AS fn,
max(case when colID = 2 then value else '' end) AS ln,
max(case when colID = 3 then value else '' end) AS jt
FROM tbl
WHERE value is not null
GROUP BY id
- Mysql:http://sqlfiddle.com/#!2/78395/1
- Postgres:http://sqlfiddle.com/#!15/78395/1
- SQLServer:http://sqlfiddle.com/#!6/78395/1
- 甲骨文:http://sqlfiddle.com/#!4/78395/1
令我惊讶的是,结果是一样的,没有一个起作用。
然后我尝试了同一查询的不同版本:
SELECT * FROM (
SELECT
id,
max(case when colID = 1 then value else '' end) AS fn,
max(case when colID = 2 then value else '' end) AS ln,
max(case when colID = 3 then value else '' end) AS jt
FROM tbl
GROUP BY id
) T
WHERE fn IS NOT NULL
AND ln IS NOT NULL
AND jt IS NOT NULL
- 甲骨文:http://sqlfiddle.com/#!4/78395/2 工作
- MySql:http://sqlfiddle.com/#!2/78395/2
- Postgres:http://sqlfiddle.com/#!15/78395/2
- SQLServer:http://sqlfiddle.com/#!6/78395/2
我可以让它在所有数据库上工作的唯一方法是使用这个查询:
SELECT
id,
max(case when colID = 1 then value else '' end) AS fn,
max(case when colID = 2 then value else '' end) AS ln,
max(case when colID = 3 then value else '' end) AS jt
FROM tbl
WHERE NOT EXISTS (SELECT * FROM tbl b WHERE tbl.id=b.id AND value IS NULL)
GROUP BY id
所以我问:
这里发生了什么,除了 Oracle 上的特定情况外,所有其他数据库似乎都忽略了IS NOT NULL 过滤器?
【问题讨论】:
-
我猜在第一个示例中,即使您排除了带有 null 的项目,您也不会排除该行/组的所有项目,并且 db 将缺失值显示为 null。顺便说一句,如果您想为缺少值的行排除整个组,这也可以; sqlfiddle.com/#!6/78395/10
-
There is no such thing as "Postgre".(好像也没有名为“My”的 RDBMS。)请解决您的问题。
-
感谢@ErwinBrandstetter,已修复。
-
顺便说一句,您使用子查询的“不同版本”是一种有效的方法。它只是失败了,因为您将original question 中的
NULL替换为'',即NOT NULL- 除了Oracle,它具有像@Joshua explains 这样的可疑实现。 -
投反对票的人愿意解释为什么这个问题被投反对票?
标签: mysql sql-server database oracle postgresql