Sql-Server

列作為獨立的項目列表

  • February 7, 2017

所以在我的數據庫中我有項目,這些項目有類別。

我創建了一個小樣本數據。

在此處輸入圖像描述

我正在創建一個報告,使用者將能夠按顏色、類別和其他一些屬性過濾項目,然後它應該在單獨的類別列中簡單地列出符合我的參數的項目。

我也不知道使用者會選擇多少個類別,因此我不知道我的報告應該有多少列。

在此處輸入圖像描述

這就是當我將它應用於我的樣本數據時的樣子。這基本上是我想要的格式,但是我想擺脫空值。我需要這些列來“獨立”列出項目,就像這樣

在此處輸入圖像描述

由於我的範例數據集中沒有 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 |
+----+------+-------+------+------+

引用自:https://dba.stackexchange.com/questions/163458