2017-06-30 7 views
1

で分離された二つの値私はこのような集約されたデータを含むテーブルを持っている:ピボットテーブル - スラッシュ

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 

今、私は列や日付などの名前で、ピボットテーブルを作成しようとしています行として。セル内部で私は以下2/5

形式でエラー状態で行数にOKステータスを持つ数または行を取得したいのですが、私が取得したいのですが、テーブルです:

Data  | A | B 
------------------------ 
2017-06-01 | 2/5 | 1/7 
2017-06-02 | 3/1 | 3/3 
2017-06-03 | 5/- | -/2 

私は別持つことができるので値はNameです。これらの値を取得するために動的クエリを作成しました。

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 TMP 
    PIVOT(SUM(Count) 
      FOR Name IN (' + @ColumnName + ')) AS PVTTable' 


EXEC sp_executesql @DynamicPivotQuery 

が、私は(私は状況によってグループ化していないよ、おそらくので)二回くらいの行を取得:

私のコードは次のようになります。

私は必要な結果をどのように得ることができますか? http://sqlfiddle.com/#!6/31770/3

答えて

0

あなたは

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 

デモリンクピボット前TotalOk/TotalErrorを計算することができます::http://rextester.com/TMAVV39610

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 

私はsqlfiddleでサンプルをビルドしました

以下のアプローチは、あなたの期待を与えるトン動的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,'[email protected]+'From 
           (
           SELECT * FROM #Temp 
           ) AS SRC 
          PIVOT 
           (
           SUM([Count]) FOR Name IN ('[email protected]+') 
           ) 
          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 
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) 
+0

@Misiuは - 悪いデータのため申し訳ありません動的問合せ –

0

まず、あなたはので、多分あなたはできません(Bのためにあなたのフィドルに間違ったデータを書きました部分期待値を参照)。 私はあなたがこのような何かを試すことができると思います(私は単なる文字列で「OK」と「エラー」を集約するために、ビットに最後のクエリを変更:

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 

UPDATED VERSION:

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' 
+0

に更新され、私はあなたの例をチェックしましたが、いくつかの理由のために私がそこにあればNULLを取得します特定のName:http://rextester.com/OSFH45159のエントリが見つからないmaxを中心にisnullを追加しようとしましたが、運がない場合 – Misiu

+0

エントリが見つからない場合、どのような価値がありますか? – etsa

+0

シンプルな ' -/- 'は細かいでしょう – Misiu