我的表包含如下聚合数据:
Name | Data | Status | Count
----------------------------------
A | 2017-06-01 | ok | 2
A | 2017-06-01 | error | 5
A | 2017-06-02 | ok | 3
A | 2017-06-02 | error | 1
A | 2017-06-03 | ok | 5
B | 2017-06-01 | ok | 1
B | 2017-06-01 | error | 7
B | 2017-06-02 | ok | 3
B | 2017-06-02 | error | 3
B | 2017-06-03 | error | 2
现在我正在尝试使用名称作为列创建数据透视表,将日期作为行创建。在单元格内部,我想获得状态为{1}}
错误状态的行数为ok的数字或行数以下是我想要的表格:
2/5
因为我在Data | A | B
------------------------
2017-06-01 | 2/5 | 1/7
2017-06-02 | 3/1 | 3/3
2017-06-03 | 5/- | -/2
列中可以有不同的值,所以我创建了动态查询来获取这些值。
我的代码如下所示:
Name
但是我获得了两次行(可能是因为我没有按状态分组)。
如何获得我需要的结果?
我在sqlfiddle中构建了示例:http://sqlfiddle.com/#!6/31770/3
答案 0 :(得分:0)
您可以在旋转之前计算TotalOk / TotalError
CREATE TABLE TMP
(
Name VARCHAR(50)
,Data VARCHAR(10)
,Status VARCHAR(20)
,Count INT
)
;
INSERT INTO TMP
(Name, Data, Status,Count)
VALUES
('A', '2017-06-01', 'ok',2),
('A', '2017-06-01', 'error',5),
('A', '2017-06-02', 'ok',3),
('A', '2017-06-02', 'error',1),
('A', '2017-06-03', 'ok',5),
('B', '2017-06-01', 'ok',2),
('B', '2017-06-01', 'error',5),
('B', '2017-06-02', 'ok',3),
('B', '2017-06-02', 'error',1),
('B', '2017-06-03', 'error',2)
;
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)
SELECT
@ColumnName = ISNULL(@ColumnName + ',', '') + QUOTENAME(Name)
FROM
( SELECT DISTINCT
Name
FROM
TMP
) AS Courses
SET @DynamicPivotQuery = N'
SELECT Data, ' + @ColumnName + '
FROM
( SELECT
t.Name, t.Data,
CONCAT( NULLIF(SUM(CASE WHEN t.Status = ''ok'' THEN t.Count ELSE 0 END),0),
''/'',
NULLIF(SUM(CASE WHEN t.Status = ''ok'' THEN 0 ELSE t.Count END),0)
) AS Count
FROM dbo.TMP t
GROUP BY t.Name, t.Data
) src
PIVOT
(
MAX(Count)
FOR Name IN (' + @ColumnName + ')
) AS PVTTable'
EXEC sp_executesql @DynamicPivotQuery
DROP TABLE dbo.TMP
答案 1 :(得分:0)
示例数据
IF OBJECT_ID('Tempdb..#Temp') IS NOT NULL
Drop table #Temp
;With cte(Name , Data, Status , [Count])
AS
(
SELECT 'A','2017-06-01' , 'ok' , 2 UNION ALL
SELECT 'A','2017-06-01' , 'error' , 5 UNION ALL
SELECT 'A','2017-06-02' , 'ok' , 3 UNION ALL
SELECT 'A','2017-06-02' , 'error' , 1 UNION ALL
SELECT 'A','2017-06-03' , 'ok' , 5 UNION ALL
SELECT 'B','2017-06-01' , 'ok' , 1 UNION ALL
SELECT 'B','2017-06-01' , 'error' , 7 UNION ALL
SELECT 'B','2017-06-02' , 'ok' , 3 UNION ALL
SELECT 'B','2017-06-02' , 'error' , 3 UNION ALL
SELECT 'B','2017-06-03' , 'error' , 2
)
SELECT * INTO #Temp From cte
SELECT * FRom #Temp
以下方法通过动态SQL方法提供您的预期结果
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX),@ColumnName2 AS NVARCHAR(MAX)
SELECT @ColumnName=STUFF((SELECT DISTINCT ', '+ QUOTENAME(Name) FROM #Temp FOR XML PATH ('')),1,1,'')
SELECT @ColumnName2=
STUFF((SELECT DISTINCT ', '+ 'REPLACE(ISNULL('+ QUOTENAME(Name) +','+'''0'''+')'+','+'''0'''+','+'''-'''+') AS '
+ QUOTENAME(Name) FROM #Temp FOR XML PATH ('')),1,1,'')
SET @DynamicPivotQuery=N'
;With Cte
AS
(
SELECT Data,'+@ColumnName2+'From
(
SELECT * FROM #Temp
) AS SRC
PIVOT
(
SUM([Count]) FOR Name IN ('+@ColumnName+')
)
PVT
)
SELECT Data ,[A],[B]
FROM (
SELECT DATA ,STUFF((SELECT ''/'' + CAST([A] AS VARCHAR(5)) FROM CTE I
WHERE I.DATA = O.DATA ORDER BY 1 DESC
FOR XML PATH('''')), 1, 1, '''') AS [A]
,STUFF((
SELECT ''/'' + CAST([B] AS VARCHAR(5)) FROM CTE I
WHERE I.DATA = O.DATA ORDER BY 1
FOR XML PATH('''')), 1, 1, '''') AS [B]
,ROW_NUMBER() OVER (PARTITION BY DATA ORDER BY DATA ) AS SEQ
FROM CTE O
) DT
WHERE DT.SEQ = 1
'
PRINT @DynamicPivotQuery
EXEC sp_executesql @DynamicPivotQuery
静态方法
;WITH cte
AS (
SELECT DISTINCT Data
,REPLACE(ISNULL([A], '0'), '0', '-') AS [A]
,REPLACE(ISNULL([B], '0'), '0', '-') AS [B]
FROM (
SELECT *
FROM #Temp
) AS SRC
PIVOT(SUM([Count]) FOR NAME IN (
[A]
,[B]
)) PVT
)
SELECT Data
,[A]
,[B]
FROM (
SELECT DATA
,STUFF((
SELECT '/' + CAST([A] AS VARCHAR(5))
FROM CTE I
WHERE I.DATA = O.DATA
ORDER BY 1 DESC
FOR XML PATH('')
), 1, 1, '') AS [A]
,STUFF((
SELECT '/' + CAST([B] AS VARCHAR(5))
FROM CTE I
WHERE I.DATA = O.DATA
ORDER BY 1
FOR XML PATH('')
), 1, 1, '') AS [B]
,ROW_NUMBER() OVER (
PARTITION BY DATA ORDER BY DATA
) AS SEQ
FROM CTE O
) DT
WHERE DT.SEQ = 1
结果
Data | A | B
------------------------
2017-06-01 | 2/5 | 1/7
2017-06-02 | 3/1 | 3/3
2017-06-03 | 5/- | -/2
答案 2 :(得分:0)
也许这可以给你一个想法。
示例数据:
IF (OBJECT_ID('tempdb..#TMP') IS NOT NULL)
BEGIN
DROP TABLE #TMP
END
CREATE TABLE #TMP
(
id INT IDENTITY(1, 1)
PRIMARY KEY ,
NAME VARCHAR(10) ,
DATA DATETIME ,
[Status] VARCHAR(20) ,
[Count] INT
)
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
INSERT INTO #TMP
( NAME, DATA, Status, Count )
VALUES ( 'A', '2017-06-01', 'ok', 2 ),
( 'A', '2017-06-01', 'error', 5 ),
( 'A', '2017-06-02', 'ok', 3 ),
( 'A', '2017-06-02', 'error', 1 ),
( 'A', '2017-06-03', 'ok', 5 ),
( 'B', '2017-06-01', 'ok', 1 ),
( 'B', '2017-06-01', 'error', 7 ),
( 'B', '2017-06-02', 'ok', 3 ),
( 'B', '2017-06-02', 'error', 3 ),
( 'B', '2017-06-03', 'error', 2 )
QUERY:
DECLARE @ColumnName AS NVARCHAR(MAX)
SELECT @ColumnName = ISNULL(@ColumnName + ',', '') + QUOTENAME(Name)
FROM ( SELECT DISTINCT
Name
FROM #TMP
) AS Courses
SET @DynamicPivotQuery = N'
SELECT CAST(DATA AS DATE) DATA,
' + @ColumnName + '
FROM ( SELECT name ,
data ,
REPLACE(CAST([A] AS VARCHAR(10)) + ''/''
+ CAST([B] AS VARCHAR(10)), ''0'', ''-'') COL
FROM ( SELECT t1.name ,
t1.data ,
ISNULL(t1.COUNT, 0) [A] ,
ISNULL(T2.Count, 0) [B]
FROM ( SELECT NAME ,
DATA ,
Status ,
Count
FROM #TMP
WHERE Status = ''ok''
) T1
LEFT JOIN ( SELECT NAME ,
DATA ,
Status ,
Count
FROM #TMP
WHERE Status = ''error''
) T2 ON T2.NAME = T1.NAME
AND T2.DATA = T1.DATA
UNION ALL
SELECT t2.name ,
t2.data ,
ISNULL(t1.COUNT, 0) [A] ,
ISNULL(T2.Count, 0) [B]
FROM ( SELECT NAME ,
DATA ,
Status ,
Count
FROM #TMP
WHERE Status = ''error''
) T2
LEFT JOIN ( SELECT NAME ,
DATA ,
Status ,
Count
FROM #TMP
WHERE Status = ''ok''
) T1 ON T2.NAME = T1.NAME
AND T2.DATA = T1.DATA
) TT
) P PIVOT ( MAX(col) FOR name IN ( '+ @ColumnName + ' ) ) PVT'
EXEC(@DynamicPivotQuery)
结果:
DATA A B
---------- ----------- ----------
2017-06-01 2/5 1/7
2017-06-02 3/1 3/3
2017-06-03 5/- -/2
(3 row(s) affected)
答案 3 :(得分:0)
首先,你在B的小提琴中写错了数据(所以也许你看不到部分预期的结果)。 我想你可以尝试这样的事情(我只是改变了一下最后一个查询,在一个字符串中聚合'ok'和'error':
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)
SELECT
@ColumnName = ISNULL(@ColumnName + ',', '') + QUOTENAME(Name)
FROM
( SELECT DISTINCT
Name
FROM
TMP
) AS Courses
SET @DynamicPivotQuery ='
SELECT * FROM
(SELECT Data, NAME, MAX(CASE WHEN STATUS=''ok'' THEN CAST(COUNT AS VARCHAR(8))
ELSE ''-'' END) +''/''
+ MAX(CASE WHEN STATUS=''error'' THEN CAST(COUNT AS VARCHAR(8)) ELSE ''-'' END) AS C
FROM TMP
GROUP BY DATA, NAME) X
PIVOT ( MAX(C) FOR Name IN (' + @ColumnName + ')) AS PVTTable'
EXEC sp_executesql @DynamicPivotQuery
输出:
Data A B
2017-06-01 2/5 1/7
2017-06-02 3/1 3/3
2017-06-03 5/- -/2
更新版本:
SET @DynamicPivotQuery ='
SELECT *
FROM (SELECT Y.DATA, Y.NAME, MAX(CASE WHEN STATUS=''ok'' THEN CAST(COUNT AS VARCHAR(8)) ELSE ''-'' END) +''/''
+ MAX(CASE WHEN STATUS=''error'' THEN CAST(COUNT AS VARCHAR(8)) ELSE ''-'' END) AS C
FROM TMP
RIGHT JOIN (SELECT DISTINCT TMP.NAME, Z.DATA
FROM TMP CROSS JOIN (SELECT DISTINCT DATA FROM TMP ) Z) Y ON TMP.NAME = Y.NAME AND TMP.DATA = Y.DATA
GROUP BY Y.DATA, Y.NAME) X
PIVOT ( MAX(C) FOR Name IN (' + @ColumnName + ')) AS PVTTable'