簡體   English   中英

在SQL Server中“旋轉”非聚合數據

[英]“Pivoting” non-aggregate data in SQL Server

這將是我在這里發布的第一個問題,因此請原諒任何無意識的董事會禮儀失誤。

在我當前的項目中,我采用了一個非規范化的大型表,並將其分解為四個獨立的規范化表。 我接觸到這個板的最終目標是創建一個模擬非規范化表以便向后兼容的視圖。

為了提供我的場景的簡化快照,我正在嘗試做的關鍵在於兩個表:

ASSOC_ROLE          ASSOCIATE
----------          ----------
assoc_id (fk)       assoc_id (pk)
role_id  (fk)       last_name
org_nbr  (fk)

所以,如果我發出以下查詢......

SELECT Assoc_Role.org_nbr, Assoc_Role.assoc_id, Associate.last_name, Assoc_Role.role_id
FROM Assoc_Role INNER JOIN
     Associate ON Assoc_Role.assoc_id = Associate.assoc_id
WHERE Assoc_Role.org_nbr = '1AA'

...我得到以下結果集

org_nbr     assoc_id     last_name     role_id
-------     --------     ---------     -------
1AA         1447         Cooper        1
1AA         1448         Collins       3
1AA         1448         Collins       4
1AA         1448         Collins       5
1AA         1449         Lynch         6

最終,我想構建的視圖看起來像這樣:

org_nbr   role1_ID   role1_name   role2_ID   role2_name   role3_ID   role3_name   role4_ID   role4_name   role5_ID   role5_name   role6_ID   role6_name
-------   --------   ----------   --------   ----------   --------   ----------   --------   ----------   --------   ----------   --------   ----------
1AA       1447       Cooper       NULL       NULL         1448       Collins      1448       Collins      1448       Collins      1449       Lynch

我最初的想法是嘗試使用PIVOT命令,但我的理解是PIVOT需要某種聚合,這不適合我的場景。 我也在SELECT子句中使用了CASE命令,但它並沒有將我的結果集壓縮到一個記錄。

希望有人可以闡明如何實現這一目標。 如果有人需要更多信息,請告訴我。 謝謝!

蘇格蘭人

要獲得基本的編號角色數據,我們可以從中開始

SELECT
    org_nbr
    , r1.assoc_id   role1_ID
    , r1.last_name  role1_name
    , r2.assoc_id   role2_ID
    , r2.last_name  role2_name
    , r3.assoc_id   role3_ID
    , r3.last_name  role3_name
    , r4.assoc_id   role4_ID
    , r4.last_name  role4_name
    , r5.assoc_id   role5_ID
    , r5.last_name  role5_name
    , r6.assoc_id   role6_ID
    , r6.last_name  role6_name
FROM
    ASSOC_ROLE ar
    LEFT JOIN ASSOCIATE r1 ON ar.role_id = 1 AND ar.assoc_id = r1.assoc_id
    LEFT JOIN ASSOCIATE r2 ON ar.role_id = 2 AND ar.assoc_id = r2.assoc_id
    LEFT JOIN ASSOCIATE r3 ON ar.role_id = 3 AND ar.assoc_id = r3.assoc_id
    LEFT JOIN ASSOCIATE r4 ON ar.role_id = 4 AND ar.assoc_id = r4.assoc_id
    LEFT JOIN ASSOCIATE r5 ON ar.role_id = 5 AND ar.assoc_id = r5.assoc_id
    LEFT JOIN ASSOCIATE r6 ON ar.role_id = 6 AND ar.assoc_id = r6.assoc_id

但是 ,對於每個org_nbr ,這將為每個具有數據的role_id一個單獨的行! 這不是我們想要的 - 所以我們需要GROUP BY org_nbr 但是,我們需要GROUP BY或聚合SELECT列表中的每一列! 接下來的技巧是提出一個聚合函數,它將安撫SQL Server 為我們提供我們想要的結果。 在這種情況下, MIN將完成這項工作:

SELECT
    org_nbr
    , MIN(r1.assoc_id)   role1_ID
    , MIN(r1.last_name)  role1_name
    , MIN(r2.assoc_id)   role2_ID
    , MIN(r2.last_name)  role2_name
    , MIN(r3.assoc_id)   role3_ID
    , MIN(r3.last_name)  role3_name
    , MIN(r4.assoc_id)   role4_ID
    , MIN(r4.last_name)  role4_name
    , MIN(r5.assoc_id)   role5_ID
    , MIN(r5.last_name)  role5_name
    , MIN(r6.assoc_id)   role6_ID
    , MIN(r6.last_name)  role6_name
FROM
    ASSOC_ROLE ar
    LEFT JOIN ASSOCIATE r1 ON ar.role_id = 1 AND ar.assoc_id = r1.assoc_id
    LEFT JOIN ASSOCIATE r2 ON ar.role_id = 2 AND ar.assoc_id = r2.assoc_id
    LEFT JOIN ASSOCIATE r3 ON ar.role_id = 3 AND ar.assoc_id = r3.assoc_id
    LEFT JOIN ASSOCIATE r4 ON ar.role_id = 4 AND ar.assoc_id = r4.assoc_id
    LEFT JOIN ASSOCIATE r5 ON ar.role_id = 5 AND ar.assoc_id = r5.assoc_id
    LEFT JOIN ASSOCIATE r6 ON ar.role_id = 6 AND ar.assoc_id = r6.assoc_id
GROUP BY
    org_nbr

輸出:

org_nbr    role1_ID    role1_name role2_ID    role2_name role3_ID    role3_name role4_ID    role4_name role5_ID    role5_name role6_ID    role6_name
---------- ----------- ---------- ----------- ---------- ----------- ---------- ----------- ---------- ----------- ---------- ----------- ----------
1AA        1447        Cooper     NULL        NULL       1448        Collins    1448        Collins    1448        Collins    1449        Lynch
Warning: Null value is eliminated by an aggregate or other SET operation.

當然,如果最大的role_id增加,這將role_id ......

如果可以,我強烈建議在常規代碼(c#,vb,無論如何)中進行這種類型的旋轉。

SQL服務器中的PIVOTing有很多缺點。 首先,超過7或8項的任何內容都會大大增加查詢所需的時間。 其次,它要求你做動態sql或提前知道所有潛在的id。 第三,難以維持。

AakashM的回答也存在同樣的問題。

我們已經嘗試了很多不同的方法來使這個工作在純SQL設置中。 對於樞軸非常有限的小型數據集,它可以正常工作。 但是,您已經擁有的角色ID數量超出了它。

相反,只需抓住數據並用您喜歡的語言創建您需要的表格。 此時要么將數據放入不同的sql表中,要么將其發送到需要的位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM