SQL Server - 使用 UNPIVOT 包含 NULL
UNPIVOT
不会返回 NULL
,但我在比较查询
中需要它们。 我试图避免在下面的示例中使用 ISNULL
(因为在真实的 sql 中有超过 100 个字段):
Select ID, theValue, column_name
From
(select ID,
ISNULL(CAST([TheColumnToCompare] AS VarChar(1000)), '') as TheColumnToCompare
from MyView
where The_Date = '04/30/2009'
) MA
UNPIVOT
(theValue FOR column_name IN
([TheColumnToCompare])
) AS unpvt
有其他选择吗?
UNPIVOT
will not return NULL
s, but I need them in a comparison query
. I am trying to avoid using ISNULL
the following example (Because in the real sql there are over 100 fields):
Select ID, theValue, column_name
From
(select ID,
ISNULL(CAST([TheColumnToCompare] AS VarChar(1000)), '') as TheColumnToCompare
from MyView
where The_Date = '04/30/2009'
) MA
UNPIVOT
(theValue FOR column_name IN
([TheColumnToCompare])
) AS unpvt
Any alternatives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
要保留 NULL,请使用 CROSS JOIN ... CASE:
而不是:
具有列模式的文本编辑器使此类查询更易于编写。 UltraEdit 有,Emacs 也有。 在 Emacs 中,这称为矩形编辑。
您可能需要为 100 列编写脚本。
To preserve NULLs, use CROSS JOIN ... CASE:
Instead of:
A text editor with column mode makes such queries easier to write. UltraEdit has it, so does Emacs. In Emacs it's called rectangular edit.
You might need to script it for 100 columns.
这真的很痛苦。 您必须在
UNPIVOT
之前将它们切换出来,因为没有生成供ISNULL()
操作的行 - 代码生成在这里是您的朋友。我在
PIVOT
上也遇到问题。 缺失的行会变成NULL
,如果缺失值与0.0
相同,则必须将其整个包裹在ISNULL()
中例如。It's a real pain. You have to switch them out before the
UNPIVOT
, because there is no row produced forISNULL()
to operate on - code generation is your friend here.I have the problem on
PIVOT
as well. Missing rows turn intoNULL
, which you have to wrap inISNULL()
all the way across the row if missing values are the same as0.0
for example.我遇到了同样的问题。 使用
CROSS APPLY
(SQL Server 2005 及更高版本)而不是Unpivot
解决了该问题。 我根据这篇文章找到了解决方案 另一种(更好?)方法取消透视我制作了以下示例来演示 CROSS APPLY 不会忽略像 Unpivot 这样的 NULL。
I ran into the same problem. Using
CROSS APPLY
(SQL Server 2005 and later) instead ofUnpivot
solved the problem. I found the solution based on this article An Alternative (Better?) Method to UNPIVOTand I made the following example to demonstrate that CROSS APPLY will NOT Ignore NULLs like
Unpivot
.或者,在 SQLServer 2008 中以更短的方式:
or, in SQLServer 2008 in shorter way:
使用动态 SQL 和 COALESCE,我解决了这样的问题:
Using dynamic SQL and COALESCE, I solved the problem like this:
我发现将 UNPIVOT 结果左外连接到完整的字段列表(可以方便地从 INFORMATION_SCHEMA 中提取)在某些情况下是此问题的实际答案。
输出看起来像:
I've found left outer joining the UNPIVOT result to the full list of fields, conveniently pulled from INFORMATION_SCHEMA, to be a practical answer to this problem in some contexts.
output looks like:
我遇到了你同样的问题,这是
我的快速而肮脏的解决方案:
您的查询:
替换为:
好的,空值将替换为字符串,但将返回所有行!
I had your same problem and this is
my quick and dirty solution :
your query :
replace with :
ok the null value is replaced with a string, but all rows will be returned !!
于 22 年 5 月撰写并在 AWS Redshift 上进行测试。
您可以使用 with 子句来合并需要空值的列。 或者,您可以在 UNPIVOT 块之前的 select 语句中使用合并。
并且不要忘记使用原始列名称别名(不遵循不会破坏或违反规则,但会节省一些喝咖啡的时间)。
或者
Writing in May'22 with testing it on AWS Redshift.
You can use a with clause where you can coalesce the columns where nulls are expected. Alternatively, you can use coalesce in the select statement prior to the UNPIVOT block.
And don't forget to alias with the original column name (Not following won't break or violate the rule but would save some time for coffee).
OR
ISNULL 是答案的一半。 使用 NULLIF 转换回 NULL。 例如,
这里我使用“0Null”作为我的中间值。 你可以使用任何你喜欢的东西。 但是,如果您选择“Null”等现实世界的内容,则可能会遇到与用户输入发生冲突的风险。 垃圾工作正常“!@#34())0”,但可能会让未来的编码人员更加困惑。 我相信你明白了。
ISNULL is half the answer. Use NULLIF to translate back to NULL. E.g.
Here I use "0Null" as my intermediate value. You can use anything you like. However, you risk collision with user input if you choose something real-world like "Null". Garbage works fine "!@#34())0" but may be more confusing to future coders. I am sure you get the picture.