我有一个大而乱的报告要写入连接5个表。一个表中有一列用于多个不同的值 - 实际上是一个“标记”列,其中标记以创造性的方式使用,具体取决于用户想要使用的各种元数据。
因此,我对报告的查询返回3个几乎相同的行,这些行仅在“tag”列中有所不同;例如,我可能会得到:
NAME TAG EMAIL
BOB A BOB@EXAMPLE.COM
BOB B BOB@EXAMPLE.COM
BOB C BOB@EXAMPLE.COM
我想要做的是将TAG列的内容拆分为3个单独的查询列,如下所示:
NAME A B C EMAIL
BOB A B C BOB@EXAMPLE.COM
所以我尝试使用SQL SERVER CASE / WHEN功能来执行此操作;我说,例如,当Tag列的值为“A”时,将其返回到“A”列;如果它是“B”,则把它放在“B”中;我认为这会返回上面的内容,但它却给了我这个:
NAME A B C EMAIL
BOB A NULL NULL BOB@EXAMPLE.COM
BOB NULL B NULL BOB@EXAMPLE.COM
BOB NULL NULL C BOB@EXAMPLE.COM
这显然不太理想。
任何想法,Stack Overflow的天才?
答案 0 :(得分:6)
您需要pivot
数据。
;with Report (name, tag, email) as
(
select 'BOB', 'A', 'BOB@BOB.COM' union
select 'BOB', 'B', 'BOB@BOB.COM' union
select 'BOB', 'C', 'BOB@BOB.COM'
)
select * from Report
pivot
( min(tag) for tag in ([A], [B], [C]))
as pvt
运行上述查询的结果如下:
NAME EMAIL A B C
-----------------------------
BOB BOB@BOB.COM A B C
答案 1 :(得分: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
,您都要告诉查询处理器您希望它将结果聚合到“桶”中,其中每个桶都由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()
也能正常工作),只是为了满足语法要求在上面的 粗体斜体 中提到..在你的情况下,集合中只会有一个非空行,所以取Min()或者Max()是必要的只是因为语法要求......