2012-10-19 60 views
2
列的其餘

我具有以下表使列值報頭用於使用TSQL

ID | Group  | Type   | Product 
1 Dairy   Milk   Fresh Milk 
2 Dairy   Butter   Butter Cream 
3 Beverage  Coke   Coca cola 
4 Beverage  Diet   Dew 
5 Beverage  Juice   Fresh Juice 

我需要以下輸出/查詢結果:

ID | Group  | Type   | Product 
1 Dairy    
1     Milk   Fresh Milk 
2     Butter   Butter Cream 
2 Beverage  
1    Coke   Coca cola 
2    Diet   Dew 
3    Juice   Fresh Juice 

對於上述樣品的硬編碼的腳本可以執行工作,但我尋找任何數量的組的動態腳本。我不知道如何做到這一點,我還沒有一個示例查詢。我需要想法,至少給我一個想法的例子。 PIVOT看起來很接近但看起來並不適合這種情況。

回答

2

這是一種可能的方法。它基本上結合了「小組標題」和「小組項目」。困難在於正確命令它們。

WITH CTE AS 
(
    SELECT ID,[Group],Type,Product, 
    ROW_NUMBER() OVER (PARTITION BY [Group] Order By ID)AS RN 
    FROM Drink 
) 
SELECT ID,[Group],Type,Product 
FROM(
    SELECT RN AS ID,[Group],[Id]AS OriginalId,'' As Type,'' As Product, 0 AS RN, 'Group' As RowType 
    FROM CTE WHERE RN = 1 
    UNION ALL 
    SELECT RN AS ID,'' AS [Group],[Id]AS OriginalId,Type,Product, RN, 'Item' As RowType 
    FROM CTE 
)X 
ORDER BY OriginalId ASC 
, CASE WHEN RowType='Group' THEN 0 ELSE 1 END ASC 
, RN ASC 

這裏有一個演示小提琴:http://sqlfiddle.com/#!6/ed6ca/2/0

2

稍微簡化的方法:

With Groups As 
    (
    Select Distinct Min(Id) As Id, [Group], '' As [Type], '' As Product 
    From dbo.Source 
    Group By [Group] 
    ) 
Select Coalesce(Cast(Z.Id As varchar(10)),'') As Id 
    , Coalesce(Z.[Group],'') As [Group] 
    , Z.[Type], Z.Product 
From (
     Select Id As Sort, Id, [Group], [Type], Product 
     From Groups 
     Union All 
     Select G.Id, Null, Null, S.[Type], S.Product 
     From dbo.Source As S 
      Join Groups As G 
       On G.[Group] = S.[Group] 
     ) As Z 
Order By Sort 

應當注意的是,使用Coalesce純粹是爲了美觀的原因。在這些情況下,您可以簡單地返回null。

SQL Fiddle

+0

OP想不完全是(僅限於組標題行,ID爲頭,但分項的行號)。 –

+0

@TimSchmelter - 簡單修復。在聯盟的第二個查詢中將該組置空。 – Thomas

0

並與ROW_NUMBER的方法:

IF OBJECT_ID('dbo.grouprows') IS NOT NULL DROP TABLE dbo.grouprows; 

CREATE TABLE dbo.grouprows(
ID INT, 
Grp NVARCHAR(MAX), 
Type NVARCHAR(MAX), 
Product NVARCHAR(MAX) 
); 
INSERT INTO dbo.grouprows VALUES 
(1,'Dairy','Milk','Fresh Milk'), 
(2,'Dairy','Butter','Butter Cream'), 
(3,'Beverage','Coke','Coca cola'), 
(4,'Beverage','Diet','Dew'), 
(5,'Beverage','Juice','Fresh Juice'); 

SELECT 
CASE WHEN gg = 0 THEN dr1 END GrpId, 
CASE WHEN gg = 1 THEN rn1 END TypeId, 
ISNULL(Grp,'')Grp, 
CASE WHEN gg = 1 THEN Type ELSE '' END Type, 
CASE WHEN gg = 1 THEN Product ELSE '' END Product 
FROM(
SELECT *, 
DENSE_RANK()OVER(ORDER BY Grp DESC) dr1 
FROM( 
SELECT *, 
ROW_NUMBER()OVER(PARTITION BY Grp ORDER BY type,gg) rn1, 
ROW_NUMBER()OVER(ORDER BY type,gg) rn0 
FROM(
SELECT Grp,Type,Product, GROUPING(Grp) gg, GROUPING(type) tg FROM dbo.grouprows 
GROUP BY Product, Type, Grp 
WITH ROLLUP 
)X1 
WHERE tg = 0 
)X2 
WHERE gg=1 OR rn1 = 1 
)X3 
ORDER BY rn0