[英]T-SQL Query that does pivot but not aggregate
Hi I have the following table of data 嗨,我有以下数据表
Class | Member | Value
----------------------
c1 | m1 | 10
c1 | m2 | 20
c1 | list | 30
c1 | list | 40
c1 | list | 50
c2 | m1 | 60
c2 | m2 | 70
c2 | list | 80
and would like to pivot the data into this form 并希望将数据转换为此表单
Class | Member 1 | Member 2 | List
----------------------------------
c1 | 10 | 20 | 30
c1 | 10 | 20 | 40
c1 | 10 | 20 | 50
c2 | 60 | 70 | 80
a normal pivot using max as the aggregate function would have given me 使用max的正常枢轴作为聚合函数会给我
Class | Member 1 | Member 2 | List
----------------------------------
c1 | 10 | 20 | 50
c2 | 60 | 70 | 80
but I want each of the List values of any Class to be listed out. 但是我希望列出任何Class的每个List值。
Instead of finding alternatives by writing SQL queries full of CASEes eg CASE Member WHEN 'm1' then Value, CASE Member WHEN 'm2' then Value, ... to achieve what I want, I want to know if there is any chance to use pivot with some tweaks to make it work for my task? 而不是通过编写充满CASE的SQL查询来找到替代方案,例如CASE成员WHEN'm1'然后是Value,CASE成员WHEN'm2'然后Value,...为了达到我想要的目的,我想知道是否有任何机会使用通过一些调整来调整以使其适用于我的任务?
The database is SQL 2008 R2 该数据库是SQL 2008 R2
Thank you 谢谢
No. PIVOT
is effectively syntactic sugar for doing aggregates around CASE
expressions. 不PIVOT
是用于围绕CASE
表达式进行聚合的有效语法糖。 If the sugar doesn't work, you need to go back to the longer form. 如果糖不起作用,你需要回到更长的形式。
The syntax for PIVOT
is fully described in the FROM
clause: PIVOT
的语法在FROM
子句中有完整描述:
<pivoted_table> ::=
table_source PIVOT <pivot_clause> [ AS ] table_alias
<pivot_clause> ::=
( aggregate_function ( value_column [ [ , ]...n ])
FOR pivot_column
IN ( <column_list> )
)
And note that aggregate_function
must be provided. 请注意,必须提供aggregate_function
。 All aggregate functions in SQL Server operate on any number of input values and produce a single output value. SQL Server中的所有聚合函数都可以对任意数量的输入值进行操作,并生成单个输出值。 There's no aggregate which can produce multiple output values, as you would require here. 没有聚合可以产生多个输出值,正如您在此需要的那样。
This gives the result you've asked for, but does rely on each Class
value only having one row for each of m1
and m2
: 这给出了您要求的结果,但是依赖于每个Class
值, m1
和m2
每一个只有一行:
declare @t table (Class char(2) not null,Member varchar(4) not null,Value int not null)
insert into @t(Class,Member,Value) values
('c1','m1',10),
('c1','m2',20),
('c1','list',30),
('c1','list',40),
('c1','list',50),
('c2','m1',60),
('c2','m2',70),
('c2','list',80)
select l.Class,m1.Value as m1,m2.Value as m2,l.Value as list
from
@t l
inner join
@t m1
on
l.Class = m1.Class and
m1.Member = 'm1'
inner join
@t m2
on
l.Class = m2.Class and
m2.Member = 'm2'where
l.Member='list'
Result: 结果:
Class m1 m2 list
----- ----------- ----------- -----------
c1 10 20 30
c1 10 20 40
c1 10 20 50
c2 60 70 80
If there are multiple rows for m1
and m2
, and you just want, say, the MAX
values for them, then you'd make m1
and m2
in my above query subqueries: 如果有多个行m1
和m2
,而你只是想,说, MAX
值它们,那么你会做m1
和m2
在我上面的查询子查询:
...
inner join
(select Class,MAX(Value) from @t where Member='m1' group by Class) m1
on
l.Class = m1.Class
...
SELECT a.*,
b.Value
FROM
(
SELECT Class,
MAX(CASE WHEN Member = 'm1' THEN Value ELSE NULL END) [Member 1],
MAX(CASE WHEN Member = 'm2' THEN Value ELSE NULL END) [Member 2]
FROM tableName
GROUP BY Class
) a
INNER JOIN
(
SELECT Class, Value
FROM tableName
WHERE Member = 'List'
) b ON a.Class = b.Class
RESULT 结果
╔═══════╦══════════╦══════════╦═══════╗
║ CLASS ║ MEMBER 1 ║ MEMBER 2 ║ VALUE ║
╠═══════╬══════════╬══════════╬═══════╣
║ c1 ║ 10 ║ 20 ║ 30 ║
║ c1 ║ 10 ║ 20 ║ 40 ║
║ c1 ║ 10 ║ 20 ║ 50 ║
║ c2 ║ 60 ║ 70 ║ 80 ║
╚═══════╩══════════╩══════════╩═══════╝
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.