如何编写SQL查询,其中从源数据表计算结果集的列

时间:2018-12-30 15:42:23

标签: sql sql-server

我有一个数据表(#t_timevalue),类似于下一个示例:

Time    Value
-------------
t1        v1
t1        v2
t1        v3
t2        v1
t2        v3
t3        v1
t4        v2
t4        v3

我正在尝试创建一个查询以汇总数据,如下所示:

Time  v1   v2   v3
t1    1    1    1
t2    1    0    1
t3    1    0    0
t4    0    1    1

where (ti,vj) = 1 if record (ti,vj) record appeared in #t_timevalue
      (ti,vj) = 0 elsewhere

是否可以使用SQL生成此类输出?

或至少目标摘要信息:

1    1    1
1    0    1
1    0    0
0    1    1

修改

Value包含未知值,并且它们的数量似乎很大。 是否推荐的解决方案来推动此报告由应用程序层而不是数据库操纵?

2 个答案:

答案 0 :(得分:1)

我认为您可以为此使用条件聚合:

select time,
       max(case when value = 'v1' then 1 else 0 end) as v1,
       max(case when value = 'v2' then 1 else 0 end) as v2,
       max(case when value = 'v3' then 1 else 0 end) as v3
from t
group by time
order by time;

编辑:

您可以使用动态数据透视表来执行此操作-如果您没有太多的值(SQL Server表或结果集中的列数受到限制):

declare @cols nvarchar(max);
declare @sql nvarchar(max);

select @cols = stuff((select distinct ', max(case when value = ''' + @value + ''' then 1 else 0 end) as ' + quotename(value) 
                      from t
                      for xml path (''), type
                     ).value( '.' , 'nvarchar(max)'
                            ), 1, 1, ''
                    ) ;

select @sql = '
select time, ' + @cols + '
from t
group by time';

exec sp_executesql @sql;

答案 1 :(得分:1)

数据透视运算符也为您工作。

create table testrr
(
[Time] varchar(30),
[Value] varchar(30)
)

insert into testrr values
('t1','v1'),
('t1','v2'),
('t1','v3'),
('t2','v1'),
('t2','v3'),
('t3','v1'),
('t4','v2'),
('t4','v3')

SELECT 
[Time],[v1],[v2],[v3]
FROM
(
SELECT 
[Time],[Value],1 AS NUMBER
FROM testrr
) SRC
PIVOT
(
 count(NUMBER) FOR [Value] IN ([v1],[v2],[v3])
) pvt

--Output
/*
Time                           v1          v2          v3
------------------------------ ----------- ----------- -----------
t1                             1           1           1
t2                             1           0           1
t3                             1           0           0
t4                             0           1           1
*/

最好的问候,