2016-10-26 59 views
2

我有一個包含三列的表格。值列始終是NULL。我知道如何將行轉置爲列,但我也想用'X'來標識單元格。轉置和標識帶有標誌的單元格

EditorTypeSymbolicName ClaimFieldSymbolicName Value 
01      AA      NULL 
01      BB      NULL 
01      CC      NULL 
02      BB      NULL 
02      CC      NULL 
03      AA      NULL 

這裏是我的代碼

DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX) 

SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ClaimFieldSymbolicName) 
      FROM #TempEditElements 
      ORDER BY 1 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)'),1,1,'') 

SET @sql = 'SELECT EditorTypeSymbolicName, ' + @cols + ' 
       FROM 
      (
       select EditorTypeSymbolicName, ClaimFieldSymbolicName, Value 
       from #TempEditElements 
      ) s 
      PIVOT 
      (
       MAX(Value) FOR ClaimFieldSymbolicName IN (' + @cols + ') 
      ) p 
      order by EditorTypeSymbolicName' 

EXECUTE(@sql) 

我的代碼對調,但我不知道如何與「X」標誌他們。我所要的輸出如:

EditorTypeSymbolicName AA BB CC 
01      X X X 
02      NULL X X 
03      X NULL NULL 

電流輸出看起來像這樣

EditorTypeSymbolicName AA BB CC 
01      NULL NULL NULL 
02      NULL NULL NULL 
03      NULL NULL NULL 
+0

你說的_identify_是什麼意思?您是否想將結果限制爲_Value_列中包含「X」的行? –

+0

電流輸出是什麼樣的?你能補充一點嗎? –

+0

@TT - 新增當前輸出。 – user176047

回答

1

這將是做這件事。在動態查詢,

  • A「矩陣」用於EditorTypeSymbolicName X ClaimFieldSymbolicName(所述CROSS JOIN部分)
  • 這然後鏈接到原始表來查找如果行存在於每個組合(所述LEFT JOIN一部分)創建
  • 如果行存在,Value取代有你需要的X(在Value=CASE ...部分)

CREATE TABLE #TempEditElements(EditorTypeSymbolicName VARCHAR(128),ClaimFieldSymbolicName VARCHAR(128),Value VARCHAR(128)); 
INSERT INTO #TempEditElements(EditorTypeSymbolicName,ClaimFieldSymbolicName,Value) 
VALUES ('01','AA',NULL),('01','BB',NULL),('01','CC',NULL),('02','BB',NULL),('02','CC',NULL),('03','AA',NULL); 

DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX); 

SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ClaimFieldSymbolicName) 
      FROM #TempEditElements 
      ORDER BY 1 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)'),1,1,'') 

SET @sql = 'SELECT EditorTypeSymbolicName, ' + @cols + ' 
       FROM 
      (
       SELECT 
        ets.EditorTypeSymbolicName, 
        cfs.ClaimFieldSymbolicName, 
        Value=CASE WHEN tee.EditorTypeSymbolicName IS NULL AND tee.ClaimFieldSymbolicName IS NULL THEN NULL ELSE ''X'' END 
       FROM 
        (SELECT DISTINCT EditorTypeSymbolicName FROM #TempEditElements) AS ets 
        CROSS JOIN (SELECT DISTINCT ClaimFieldSymbolicName FROM #TempEditElements) AS cfs 
        LEFT JOIN #TempEditElements AS tee ON 
         tee.EditorTypeSymbolicName=ets.EditorTypeSymbolicName AND 
         tee.ClaimFieldSymbolicName=cfs.ClaimFieldSymbolicName 
      ) s 
      PIVOT 
      (
       MAX(Value) FOR ClaimFieldSymbolicName IN (' + @cols + ') 
      ) p 
      order by EditorTypeSymbolicName' 

EXECUTE (@sql); 

DROP TABLE #TempEditElements; 

結果是:

╔════════════════════════╦══════╦══════╦══════╗ 
║ EditorTypeSymbolicName ║ AA ║ BB ║ CC ║ 
╠════════════════════════╬══════╬══════╬══════╣ 
║      01 ║ X ║ X ║ X ║ 
║      02 ║ NULL ║ X ║ X ║ 
║      03 ║ X ║ NULL ║ NULL ║ 
╚════════════════════════╩══════╩══════╩══════╝ 
+0

謝謝你soln: – user176047

+0

**(1)**應該沒有**值的邏輯**它只是**'X'** ** (2)** PIVOT的工作方式,沒有理由生成** EditorTypeSymbolicName **和** ClaimFieldSymbolicName **的所有組合。一旦您在** EditorTypeSymbolicName **中有值,將在數據透視表中創建一行。對於基於** ClaimFieldSymbolicName **創建的列,您已經在上一部分中注意了。如果原始表中至少有一行使用** EditorTypeSymbolicName **和** ClaimFieldSymbolicName **值,否則數據透視表中的任何方塊都將保留「X」,否則將保留「X」。 –

+0

@DuduMarkovitz你有一個點。對於像這樣的問題,我並不是真正的解決方案是最好的,我只是做了一些有用的東西。 –

1

靜態解

select  * 

from  (select 'X' as x,EditorTypeSymbolicName,ClaimFieldSymbolicName from t) t 
       pivot (max(x) for ClaimFieldSymbolicName in ([AA],[BB],[CC])) t 

order by EditorTypeSymbolicName 
; 

動態的解決方案

declare @columns nvarchar(max) = '' 
     ,@stmt  nvarchar(max) 
; 

---------- 

select  @columns += case @columns when '' then '' else ',' end + QUOTENAME (ClaimFieldSymbolicName,'[') 

from  t 

group by ClaimFieldSymbolicName 

order by ClaimFieldSymbolicName 
; 

---------- 

set @stmt = 

    ' 
    select  * 

    from  (select ''X'' as x,EditorTypeSymbolicName,ClaimFieldSymbolicName from t) t 
        pivot (max(x) for ClaimFieldSymbolicName in ('+ @columns + ')) t 

    order by EditorTypeSymbolicName 
    ' 
; 

---------- 

exec (@stmt) 

半靜態解

select  (select top 0 EditorTypeSymbolicName from t) as EditorTypeSymbolicName,t.* 

from  (select distinct ClaimFieldSymbolicName,dense_rank() over (order by ClaimFieldSymbolicName) as dr from t) t 
       pivot (max(ClaimFieldSymbolicName) for dr in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) t 


union all 

select  * 

from  (select 'X' as x,EditorTypeSymbolicName,dense_rank() over (order by ClaimFieldSymbolicName) as dr from t) t 
       pivot (max(x) for dr in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) t 

order by 1 
; 

╔════════════════════════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╗ 
║ EditorTypeSymbolicName ║ 1 ║ 2 ║ 3 ║ 4 ║ 5 ║ 6 ║ 7 ║ 8 ║ 9 ║ 10 ║ 
╠════════════════════════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╣ 
║ NULL     ║ AA ║ BB ║ CC ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ 
║ 01      ║ X ║ X ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ 
║ 02      ║ NULL ║ X ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ 
║ 03      ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ 
╚════════════════════════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╝ 
+0

我需要它是動態的,因爲轉置列的數量很多 – user176047

+0

@ user176047,這意味着你只需要連接列標識符,例如** AA,BB,CC **並將其推送到此查詢中。我相信你會這麼做 –

+0

是的,我嘗試使用'at'cols'('at'cols)中的t.ClaimFieldSymbolicName)「但我得到一個語法錯誤。我聲明'at'cols並將其填入列名,就像在我上面的OP查詢中一樣。 – user176047

相關問題