列作為獨立的項目列表
所以在我的數據庫中我有項目,這些項目有類別。
我創建了一個小樣本數據。
我正在創建一個報告,使用者將能夠按顏色、類別和其他一些屬性過濾項目,然後它應該在單獨的類別列中簡單地列出符合我的參數的項目。
我也不知道使用者會選擇多少個類別,因此我不知道我的報告應該有多少列。
這就是當我將它應用於我的樣本數據時的樣子。這基本上是我想要的格式,但是我想擺脫空值。我需要這些列來“獨立”列出項目,就像這樣
由於我的範例數據集中沒有 XX 類別的項目,因此該列不存在。其餘的被“聚合”。
好的,這讓我想到了我的主要問題。或者問題,更確切地說,我想我有兩個。
1)我是SQL新手,如果我錯了,我還在學習,所以請糾正我,但我認為這只是關係數據庫中“不應該執行”的任務,我是否正確?我覺得這違反了核心規則,即一行是一個數據,一個條目。在這裡,我的一行變成了三個(或更多/更少)的數據,它們之間沒有明確的關係。
我以前必須做一個報告,我並排顯示兩個項目,使用者可以選擇左側的商店,右側的另一家商店,並查看“左側組”中最暢銷的商品和最暢銷的商品來自“正確的群體”。所以我只是按 ROW_NUMBER 生成的排名加入了這兩個組,我的數據從“每個條目一件商品”更改為“每個條目在所選商店中的第 N 個位置”。這是有道理的。
至少就我目前的理解而言,這裡沒有。但這讓我想到了第二個問題:
2)他們仍然希望我這樣做。我如何能?
到目前為止,我已經想到了兩種可能的解決方案。
一種是我分別選擇類別,然後根據某種 ROW_NUMBER 將它們連接在一起,以確保一對一的關係(我並不關心排序)
因此,如果我想要的類別是“OD”、“AL”、“UT”,我會用 3 個單獨的查詢將它們取出,就像這樣
SELECT ROW_NUMBER() OVER (ORDER BY (select null)) AS rn ,Item ,Category INTO #OD FROM sth WHERE Category = 'OD'
每個類別依此類推,然後使用“rn”列將它們連接在一起。這可行,但因為我不知道報告使用者會選擇多少個類別,所以會出現問題。也許這可以通過動態 SQL 來完成?我不確定,我也不是很喜歡使用它……
我也想過一個不同的解決方案,但我不確定這是否可行。如果有可能以某種方式分配這樣的數字:
因此,第 1 行標記為“1”,因為它是它遇到的“OD”的第一個值。第 2 行也被標記為“1”,因為它是它遇到的“AL”的第一個錯誤。這樣,第 4 行標記為“2”,第 5 行標記為“3”,因為它分別是“OD”列的第二個和第三個值。然後第 6 行再次標記為“2”,因為它是“AL”列的第二個值。
這樣我就可以使用 MAX() 函式並按分配的數字進行分組。所有分配為 1 的行將聚合到一行,所有分配為 2 的行將聚合到另一行等。我確信在我的數據透視表中每行會有一個項目,因為一個項目不能屬於兩個類別。
我也覺得以動態方式(未知的列數 - 選擇的類別)執行該解決方案會容易得多,但我無法弄清楚如何獲得這樣的編號以及是否可能。
期待你們的回答,我被困住了!
我認為這就是你要找的:
測試設置:http ://rextester.com/SGKW56535
create table t (Item int, Kategoria char(2)) insert into t values (1111,'OD') , (2222,'AL') , (1234,'UT') , (1122,'OD') , (4321,'OD') , (5555,'AL') , (6666,'UT') , (65577,'AX');
row_number()
分區查詢Kategoria
:select rn=row_number() over ( partition by Kategoria order by Item ) , Item , Kategoria from t;
結果:
+----+-------+-----------+ | rn | Item | Kategoria | +----+-------+-----------+ | 1 | 2222 | AL | | 2 | 5555 | AL | | 1 | 65577 | AX | | 1 | 1111 | OD | | 2 | 1122 | OD | | 3 | 4321 | OD | | 1 | 1234 | UT | | 2 | 6666 | UT | +----+-------+-----------+
硬編碼樞軸範例:
with cte as ( select rn=row_number() over ( partition by Kategoria order by Item ) , Item , Kategoria from t ) select rn, OD, AL, UT from cte pivot (max(Item) for Kategoria in (OD, AL, UT) ) p;
結果:
+----+------+------+------+ | rn | OD | AL | UT | +----+------+------+------+ | 1 | 1111 | 2222 | 1234 | | 2 | 1122 | 5555 | 6666 | | 3 | 4321 | NULL | NULL | +----+------+------+------+
動態樞軸範例:
declare @cols nvarchar(max); declare @sql nvarchar(max); select @cols = stuff(( select distinct ',' + quotename(Kategoria) from t for xml path (''), type).value('.','nvarchar(max)') ,1,1,'') select @sql = ' select rn, ' + @cols + ' from ( select Kategoria , Item , rn=row_number() over ( partition by Kategoria order by Item ) from t ) as a pivot (max([Item]) for [Kategoria] in (' + @cols + ') ) p' select @sql exec(@sql);
生成的sql:
select rn, [AL],[AX],[OD],[UT] from ( select Kategoria , Item , rn=row_number() over ( partition by Kategoria order by Item ) from t ) as a pivot (max([Item]) for [Kategoria] in ([AL],[AX],[OD],[UT]) ) p
動態sql結果:
+----+------+-------+------+------+ | rn | AL | AX | OD | UT | +----+------+-------+------+------+ | 1 | 2222 | 65577 | 1111 | 1234 | | 2 | 5555 | NULL | 1122 | 6666 | | 3 | NULL | NULL | 4321 | NULL | +----+------+-------+------+------+