我有一张桌子,里面有活动和发生的那天:
表'事件':
Name Day
-----------
A 1
B 2
A 2
B 3
我需要输出列作为基于查询输入的日期范围,其中行是当天发生的事件,所以:
期望的输出:
Day-1 Day-2 Day-3
-----------------
A A -
- B B
如果有可能,任何人都可以给我一个样本查询,可以根据日期范围生成此输出。有各种各样的我不知道如何在这里处理这个问题,就像未知数量的列。
答案 0 :(得分:3)
您可以使用条件聚合:
select max(case when day = 1 then name end) as day_1,
max(case when day = 2 then name end) as day_2,
max(case when day = 3 then name end) as day_3
from t
group by name;
注意:这会返回NULL
而不是-
。我认为NULL
更有意义。
答案 1 :(得分:2)
试试这个...
表脚本和示例数据
CREATE TABLE [TableName](
[Name] [nvarchar](50) NULL,
[Day] [int] NULL
)
INSERT [TableName] ([Name], [Day]) VALUES (N'A', 1)
INSERT [TableName] ([Name], [Day]) VALUES (N'B', 2)
INSERT [TableName] ([Name], [Day]) VALUES (N'A', 2)
INSERT [TableName] ([Name], [Day]) VALUES (N'B', 3)
查询(动态PIVOT)
DECLARE @startDay AS INT;
DECLARE @endDay AS INT;
SET @startDay = 1;
SET @endDay = 3;
DECLARE @cols AS NVARCHAR(max) = Stuff((SELECT DISTINCT ',' + Quotename([day])
FROM TableName
WHERE [Day] >= @startDay AND [Day] <= @endDay
FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
DECLARE @query AS NVARCHAR(max) = 'SELECT '+ @cols +'
FROM (SELECT *,
Dense_rank() OVER (ORDER BY NAME) AS dr
FROM TableName) sq
PIVOT(Max([name])
FOR [day] IN ('+ @cols +') ) pvt ';
EXECUTE(@query)
输出
+--------+---+--------+
| 1 | 2 | 3 |
+--------+---+--------+
| A | A | (null) |
| (null) | B | B |
+--------+---+--------+
在线演示:http://www.sqlfiddle.com/#!18/c688b/8/0
如果您还想使用自定义列名,请尝试此操作...
DECLARE @startDay AS INT;
DECLARE @endDay AS INT;
SET @startDay = 1;
SET @endDay = 3;
DECLARE @cols AS NVARCHAR(max) = Stuff((SELECT DISTINCT ',' + Quotename([day])
FROM TableName
WHERE [Day] >= @startDay AND [Day] <= @endDay
FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
DECLARE @colNames AS NVARCHAR(max) = Stuff((SELECT DISTINCT ',' + Quotename([day]) + ' AS Days' + CONVERT(NVARCHAR(MAX), [day])
FROM TableName
WHERE [Day] >= @startDay AND [Day] <= @endDay
FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
DECLARE @query AS NVARCHAR(max) = 'SELECT '+ @colNames +'
FROM (SELECT *,
Dense_rank() OVER (ORDER BY NAME) AS dr
FROM TableName) sq
PIVOT(Max([name])
FOR [day] IN ('+ @cols +') ) pvt ';
EXECUTE(@query)
输出
+-------+-------+-------+
| Days1 | Days2 | Days3 |
+-------+-------+-------+
| A | A | NULL |
| NULL | B | B |
+-------+-------+-------+