2010-09-16 129 views
2

我有一个大的杂乱的报告来编写跨5个表的连接。一张表中有一列用于多个不同的值 - 本质上是一个“标签”列,其中标签以创造性的方式使用,取决于用户想要使用什么样的其他元数据。在SQL Server SELECT语句中使用CASE时消除NULL NULL

结果,我对报告查询返回3不同之处仅在“标签”一栏几乎相同的行;举例来说,我可能会得到:

NAME TAG EMAIL 
BOB A [email protected] 
BOB B [email protected] 
BOB C [email protected] 

我想要做的是分裂TAG列的内容要返回从查询3个独立的栏目,像这样的内容:

NAME A B C EMAIL 
BOB A B C [email protected] 

所以我尝试使用SQL SERVER CASE/WHEN功能来执行此操作;我在说,例如,当标签列的值是“A”时,将它返回到列“A”;如果是“B”,则放入“B”;等等。我认为这将返回上面的,而是它给了我这样的:

NAME A B C EMAIL 
BOB A NULL NULL [email protected] 
BOB NULL B NULL [email protected] 
BOB NULL NULL C [email protected] 

其中明确不太理想。

任何想法,堆栈溢出的天才?

回答

5

试试这个:

Select Name, 
    Min (Case When tag = 'A' Then Tag End) A, 
    Min (Case When tag = 'B' Then Tag End) B, 
    Min (Case When tag = 'C' Then Tag End) C, 
    email 
    From tableName 
    Group By Name, email 

编辑:解释...
每当你使用一个Group By,您告诉查询处理器您希望它将结果聚合到“桶”中,其中每个桶由列[或表达式]中的唯一值定义def在Group By子句中定义。这意味着最终结果集对于Group By中定义的那些列[或表达式]中的每个唯一值集合将只有一行。在查询中使用的所有其它列或表达式,(除那些在分组方式定义的其他),必须是基于聚合函数的表达式(如COUNT(),SUM(),AVG(),MIN( ),Max()等),根据计算结果生成一个值,该计算将应用于预汇总结果集中的所有行。如果,例如,我是来Group By姓氏的第一个字符:

Select Left(LastName, 1), Count(*), 
    Sum(Salaray, Avg(Height), 
    Min(DateOfBirth), etc. 
    From Table 
    Group By Left(LastName, 1) 

然后我会在输出(一个字母表中的每个字母)最多26行和所有其他列我输出必须根据被应用到原来设定的所有行的一些聚合功能,其中姓与“A”,那么所有在那里的姓氏与QA开始行‘B’等。

开始

在你的问题中,Group By只用于限制每个不同用户和电子邮件的输出设置为一行,一旦完成,只会有一行。Select语句中的其他列需要有一个Min(), [Max()将工作一样),只是为了满足粗斜体以上提到的syntacical要求..在你的情况下,将只有一个非null行的集合,所以采取Min(),或Max()是必要的,因为语法要求...

+0

我想我得到为什么这有助于,但你能解释一下吗?我为我明显的无知道歉。 – SuperNES 2010-09-17 13:22:10

+0

编辑答案添加说明.. – 2010-09-17 15:53:48

6

您需要pivot数据。

;with Report (name, tag, email) as 
(
select 'BOB', 'A', '[email protected]' union 
select 'BOB', 'B', '[email protected]' union 
select 'BOB', 'C', '[email protected]' 
) 
select * from Report 
pivot 
(min(tag) for tag in ([A], [B], [C])) 
as pvt 

并运行上述查询的结果是这样的:

NAME EMAIL   A B C 
----------------------------- 
BOB  [email protected] A B C