有人可以帮我解决这个SQL查询问题。
在下表中,RESPONSES计算SEGMENT的次数 在CHECKED日期回复。
CREATE TABLE #TEST (ID INT, SEGMENT CHAR(1),RESPONSES
INT,CHECKED SMALLDATETIME)
INSERT INTO #TEST VALUES (1,'A',0,'2009-05-01')
INSERT INTO #TEST VALUES (2,'B',1,'2009-05-01')
INSERT INTO #TEST VALUES (3,'C',0,'2009-05-01')
INSERT INTO #TEST VALUES (4,'A',0,'2009-05-02')
INSERT INTO #TEST VALUES (5,'B',2,'2009-05-02')
INSERT INTO #TEST VALUES (6,'C',1,'2009-05-02')
INSERT INTO #TEST VALUES (7,'A',1,'2009-05-03')
INSERT INTO #TEST VALUES (8,'B',0,'2009-05-03')
INSERT INTO #TEST VALUES (9,'C',2,'2009-05-03')
撰写查询以总结每个SEGMENT和每个SEGMENT的总回复 检查日期,如下所示:
CHECKED A B C
2009-5-01 0 1 0
2009-5-02 0 2 1
2009-5-03 1 0 2
不要将段名称(即“A”,“B”,“C”)硬编码到解决方案中,因此 如果添加更多片段(例如“D”)或片段,则解决方案保持有效 重命名(例如“A” - >“X”)。
答案 0 :(得分:2)
您需要使用动态SQL。有关示例,请参阅此blog post。 Another example,不同的博客,同样的方法。
如果您的列是静态的并且您使用的是SQL Server 2005及更高版本,则可以使用PIVOT功能来执行此类查询。
答案 1 :(得分:2)
Select Checked
, Sum( Case When Segment = 'A' Then 1 Else 0 End ) As A
, Sum( Case When Segment = 'B' Then 1 Else 0 End ) As B
, Sum( Case When Segment = 'C' Then 1 Else 0 End ) As C
From #Test
Group By Checked
此类查询通常称为交叉表查询。上述解决方案假定您要静态声明要查看的列。如果要动态确定列,那么您所寻求的是动态交叉表,并且它无法在SQL语言中本机完成。 SQL语言不是为动态列生成而设计的。解决方案是在中间层构建查询。
答案 2 :(得分:1)
请在StackOverFlow上看到:如果使用的是SQL Server 2005或更高版本......
DECLARE @test TABLE
(
ID INT,
SEGMENT CHAR(1),
RESPONSES INT,
CHECKED SMALLDATETIME
)
INSERT INTO @test VALUES (1,'A',0,'2009-05-01')
INSERT INTO @test VALUES (2,'B',1,'2009-05-01')
INSERT INTO @test VALUES (3,'C',0,'2009-05-01')
INSERT INTO @test VALUES (4,'A',0,'2009-05-02')
INSERT INTO @test VALUES (5,'B',2,'2009-05-02')
INSERT INTO @test VALUES (6,'C',1,'2009-05-02')
INSERT INTO @test VALUES (7,'A',1,'2009-05-03')
INSERT INTO @test VALUES (8,'B',0,'2009-05-03')
INSERT INTO @test VALUES (9,'C',2,'2009-05-03')
SELECT * FROM
(
SELECT SEGMENT,
RESPONSES,
CHECKED
FROM @test
) AS subquery
PIVOT
(
SUM(responses)
FOR SEGMENT IN ([a],[b],[c])
) AS pivotquery
动态SQL示例
CREATE TABLE ##test
(
ID INT,
SEGMENT CHAR(1),
RESPONSES INT,
CHECKED SMALLDATETIME
)
INSERT INTO ##test VALUES (1,'A',0,'2009-05-01')
INSERT INTO ##test VALUES (2,'B',1,'2009-05-01')
INSERT INTO ##test VALUES (3,'C',0,'2009-05-01')
INSERT INTO ##test VALUES (4,'A',0,'2009-05-02')
INSERT INTO ##test VALUES (5,'B',2,'2009-05-02')
INSERT INTO ##test VALUES (6,'C',1,'2009-05-02')
INSERT INTO ##test VALUES (7,'A',1,'2009-05-03')
INSERT INTO ##test VALUES (8,'B',0,'2009-05-03')
INSERT INTO ##test VALUES (9,'C',2,'2009-05-03')
DECLARE @SQLa VARCHAR(255),
@SQLb VARCHAR(255),
@SQLc VARCHAR(255)
SET @SQLa =
'SELECT * FROM
(
SELECT SEGMENT,
RESPONSES,
CHECKED
FROM ##test
) AS subquery
PIVOT
(
SUM(responses)
FOR SEGMENT IN ('
SET @SQLc = ')
) AS pivotquery'
SELECT @sqlB = STUFF(
(
SELECT ',[' + SEGMENT + ']'
FROM ##test WITH (NOLOCK)
GROUP BY SEGMENT
FOR XML PATH('')
),1, 1, '')
EXECUTE (@SQLa + @SQLb + @SQLc)
DROP TABLE ##test