简体   繁体   English

执行数据透视但不聚合的T-SQL查询

[英]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值, m1m2每一个只有一行:

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: 如果多个行m1m2 ,而你只是想,说, MAX值它们,那么你会做m1m2在我上面的查询子查询:

...
    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM