2017-09-07 50 views
5

我有一個表看起來像這樣樞行14列,7元組

assignmentID personID projectCode projectCodePercent 
-------------- ------------ ----------- ----------- 
642    13527  511   75.00 
642    13527  621   25.00 
650    12000  555   50.00 
650    12000  520   25.00 
650    12000  621   25.00 
240    56000  721   100.00 

我想知道(porjectCode,projectCodePercent)作爲元組對每個應用的分佈。一個賦值最多可以有7個元組。如果他們沒有7,那麼這些領域可能只是空白。所以期望的輸出應該看起來如下:

assignmentID projectCode1 projectCodePercent1 projectCode2 projectCodePercent2 projectCode3 projectCodePercent3 projectCode4 projectCodePercent4 projectCode5 projectCodePercent5 projectCode6 projectCodePercent6 projectCode7 projectCodePercent7 
------------ ------------ ------------------- ------------ ------------------- ------------- ------------------- ------------- ------------------- ------------- ------------------- ------------- ------------------- ------------ ---------------- 
642   511   75.00     621   25.00 
650   555   50.00     520   25.00     621    25.00 
240   721   100.00 

編輯:記錄順序無關緊要。即。其中記錄獲得分配給projectCode1或projectCode2 ....等等,只要正確projectCode相符的正確projectCodePercent

+0

什麼定義記錄訂單?爲什麼520 projectcode2而不是555或621?隨機?沒關係? – xQbert

+0

@xQbert謝謝澄清。記錄順序無關緊要。 –

回答

3

因爲你並不需要去動態。一種方法是通過CROSS APPLY UNPivot數據。

Select * 
From (
     Select assignmentID  
       ,B.* 
      From (
        Select *,Grp = Row_Number() over (Partition By assignmentID order by projectCode) 
        From YourTable 
       ) A 
      Cross Apply (values ('projectCode'  +left(A.Grp,1),cast(projectCode as varchar(max))) 
           ,('projectCodePercent'+left(A.Grp,1),cast(projectCodePercent as varchar(max))) 
           ,('projectCode'  +left(A.Grp,1),cast(projectCode as varchar(max))) 
         ) B(Item,Value) 
    ) A 
Pivot (max([Value]) For [Item] in (projectCode1,projectCodePercent1,projectCode2,projectCodePercent2,projectCode3,projectCodePercent3,projectCode4,projectCodePercent4,projectCode5,projectCodePercent5,projectCode6,projectCodePercent6,projectCode7,projectCodePercent7)) p 

返回

enter image description here

+1

比我所做的更清潔(從執行角度看)。我真的需要玩更多的交叉應用。雖然我不羨慕最初必須維持上述內容的新人:P – xQbert

+1

@xQbert由於這是一個固定的數字,我的第一個想法就是你的方法。只需提供一個替代品。 –

+2

這是一個很好的例子:P應該總是在可以的時候利用新功能。他們通常提供顯着的好處。 – xQbert

4

DEMO不要緊:http://rextester.com/IYDJ29385

  1. CTE給我的樣本數據與
  2. CTE2簡單地爲每個assignmentId和PersonId分配一個行號(您可以只使用一個內聯視圖)
  3. 然後我們使用case語句來基於生成的行號來轉發數據。這種方法的缺點是總是返回14列。使用動態SQL,您只能在需要時顯示這些列。

這確實假定assignmentId和personId和projectcode是唯一的。如果同一個作業和人員可能存在多個項目代碼,那麼我們需要做一些不同的事情,而不是最大化。

WITH CTE (assignmentID, personID, projectCode, projectCodePercent) as (
SELECT 642,    13527,  511,   75.00 UNION ALL 
SELECT 642,    13527,  621,   25.00 UNION ALL 
SELECT 650,    12000,  555,   50.00 UNION ALL 
SELECT 650,    12000,  520,   25.00 UNION ALL 
SELECT 650,    12000,  621,   25.00 UNION ALL 
SELECT 240,    56000,  721,   100.00), 
cte2 as (SELECT A.*, row_number() over (partition by AssignmentID, PersonID order by projectCode) RN 
     FROM cte A) 
SELECT AssignmentID 
    , PersonID 
    , max(CASE WHEN RN = 1 then projectCode end) as projectCode1 
    , max(CASE WHEN RN = 1 then ProjectcodePercent end) as ProjectcodePercent1 
    , max(CASE WHEN RN = 2 then projectCode end) as projectCode2 
    , max(CASE WHEN RN = 2 then ProjectcodePercent end) as ProjectcodePercent2 
    , max(CASE WHEN RN = 3 then projectCode end) as projectCode3 
    , max(CASE WHEN RN = 3 then ProjectcodePercent end) as ProjectcodePercent3 
    , max(CASE WHEN RN = 4 then projectCode end) as projectCode4 
    , max(CASE WHEN RN = 4 then ProjectcodePercent end) as ProjectcodePercent4 
    , max(CASE WHEN RN = 5 then projectCode end) as projectCode5 
    , max(CASE WHEN RN = 5 then ProjectcodePercent end) as ProjectcodePercent5 
    , max(CASE WHEN RN = 6 then projectCode end) as projectCode6 
    , max(CASE WHEN RN = 6 then ProjectcodePercent end) as ProjectcodePercent6 
    , max(CASE WHEN RN = 7 then projectCode end) as projectCode7 
    , max(CASE WHEN RN = 7 then ProjectcodePercent end) as ProjectcodePercent7 
FROM CTE2 
Group by AssignmentID, personId 

給予我們:

+----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+ 
| | AssignmentID | PersonID | projectCode1 | ProjectcodePercent1 | projectCode2 | ProjectcodePercent2 | projectCode3 | ProjectcodePercent3 | projectCode4 | ProjectcodePercent4 | projectCode5 | ProjectcodePercent5 | projectCode6 | ProjectcodePercent6 | projectCode7 | ProjectcodePercent7 | 
+----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+ 
| 1 |   650 | 12000 |   520 |    25,00 | 555   | 50,00    | 621   | 25,00    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | 
| 2 |   642 | 13527 |   511 |    75,00 | 621   | 25,00    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | 
| 3 |   240 | 56000 |   721 |    100,00 | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | 
+----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+ 
+0

從執行計劃的角度來看更好的選擇 – JamieD77

+0

+ 1謝謝。我喜歡這個,因爲它很容易理解。我打算使用這個作爲我的子查詢。我目前的查詢已經非常龐大和複雜,所以我可能會在下面使用John的答案。 –

+0

複雜的SQL是CTE創建的一個原因IMO:P – xQbert