2015-07-13 64 views
3

我試圖做一個PIVOT桌子上有兩行是這樣的:SQL樞軸只有兩列

Category  | Sector 
--------------------------- 
Bulbs   | DIY 
Bulbs   | Home 
Picnic blanket | DIY 
Picnic blanket | Home 
Picnic blanket | Interior 

每個類別可以有1個或多個部門。

我想要得到這樣一個表:

Category  | Sector 1 | Sector 2 | Sector 3 
------------------------------------------------- 
Bulbs   | DIY  | Home  | NULL 
Picnic blanket | DIY  | Home  | Interior 

查詢看起來是這樣的:

SELECT 
    dbo.fn_DbContent_GetTranslation(pt.Name_DbContentId, 2) 'Category' 
    , dbo.fn_DbContent_GetTranslation(s.Name_DbContentId, 2) 'Sector' 
FROM dbo.ProductType pt 
JOIN dbo.ProductTypeMandator ptm ON ptm.ProductTypeId = pt.Id 
JOIN dbo.ProductTypeMandator2PortalSector ptmps ON ptmps.ProductTypeMandatorId = ptm.Id 
JOIN dbo.PortalSector ps ON ps.Id = ptmps.PortalSectorId 
JOIN dbo.Sector s ON s.Id = ps.SectorId 
WHERE 
    ptmps.PortalSectorId IN (21, 18, 19) 

我已經做了PIVOT但包含三列,其中一個包含的表數據透視表中標題的值。在這種情況下,標題的值已丟失,所以我不知道如何去做。

感謝您的幫助

+2

您想要顯示的扇區數量和/或數量是否有限制?任何單獨的查詢都有一個固定的「形狀」(列的數量,名稱和數據類型),所以如果您需要支持無限數量,那麼您正在查看動態SQL來構建查詢。 –

+0

你是怎麼得到這個訂單的?扇區1,扇區2 ..? –

回答

2

可以解決這樣的說法:

-- Create demo data 
CREATE TABLE #cats(category nvarchar(25), sector nvarchar(25)) 

INSERT INTO #cats(category, sector) 
VALUES (N'Bulbs',N'DIY'), 
     (N'Bulbs',N'Home'), 
     (N'Picnic blanket',N'DIY'), 
     (N'Picnic blanket',N'Home'), 
     (N'Picnic blanket',N'Interior') 

SELECT * 
FROM (
    SELECT category, sector 
    FROM #cats 
) as dat 
PIVOT(
    MAX(sector) 
    FOR sector IN([DIY],[Home],[Interior]) 
) as pvt 

-- Cleanup 
DROP TABLE #cats 

如果你希望它是正確地命名爲你的榜樣,你可以用一個命名編號結合起來:

-- Create demo data 
CREATE TABLE #cats(category nvarchar(25), sector nvarchar(25)) 

INSERT INTO #cats(category, sector) 
VALUES (N'Bulbs',N'DIY'), 
     (N'Bulbs',N'Home'), 
     (N'Picnic blanket',N'DIY'), 
     (N'Picnic blanket',N'Home'), 
     (N'Picnic blanket',N'Interior') 

SELECT * 
FROM (
    SELECT category, sector, N'Sector '+CONVERT(nvarchar(max),DENSE_RANK() OVER(ORDER BY sector)) as rn 
    FROM #cats 
) as dat 
PIVOT(
    MAX(sector) 
    FOR rn IN([Sector 1],[Sector 2],[Sector 3]) 
) as pvt 

-- Cleanup 
DROP TABLE #cats 

最後但並非最不重要的,如果你希望它是動態:

-- Create demo data 
CREATE TABLE #cats(category nvarchar(25), sector nvarchar(25)) 

INSERT INTO #cats(category, sector) 
VALUES (N'Bulbs',N'DIY'), 
     (N'Bulbs',N'Home'), 
     (N'Picnic blanket',N'DIY'), 
     (N'Picnic blanket',N'Home'), 
     (N'Picnic blanket',N'Interior') 

DECLARE @sql nvarchar(max), @cols nvarchar(max) 

-- get proper column list 
SELECT @cols = COALESCE(@cols + N',[' + grCols.rn + N']',N'[' + grCols.rn + N']') 
FROM (
    SELECT DISTINCT N'Sector '+CONVERT(nvarchar(max),DENSE_RANK() OVER(ORDER BY sector)) as rn 
    FROM #cats 
) as grCols 

SET @sql = N' 
SELECT * 
FROM (
    SELECT category, sector, N''Sector ''+CONVERT(nvarchar(max),DENSE_RANK() OVER(ORDER BY sector)) as rn 
    FROM #cats 
) as dat 
PIVOT(
    MAX(sector) 
    FOR rn IN('[email protected]+') 
) as pvt' 
EXEC(@sql) 

-- Cleanup 
DROP TABLE #cats 
+0

完全爲我工作,謝謝! – sandrowi

+0

很高興幫助你。 – Ionic

0

您可以通過兩種方式做到這一點,

一是Conditional Aggregate

;WITH cte 
    AS (SELECT *, 
       rn=Row_number() 
        OVER(
         partition BY category 
         ORDER BY (SELECT NULL)) 
     FROM yourtable) 
SELECT category, 
     [sector 1] = Max(CASE WHEN rn = 1 THEN sector END), 
     [sector 2] = Max(CASE WHEN rn = 2 THEN sector END), 
     [sector 3] = Max(CASE WHEN rn = 3 THEN sector END) 
FROM cte 
GROUP BY category 

另一種方法是使用Pivot

SELECT * 
FROM (SELECT *, 
       sector_col = 'sector ' 
          + Cast(Row_number()OVER(partition BY category ORDER BY (SELECT NULL)) AS VARCHAR(20)) 
     FROM yourtable) A 
     PIVOT (Max(sector) 
      FOR sector_col IN ([sector 1], 
           [sector 2], 
           [sector 3])) piv 

注:正如如果sector值評論提到不是staticunknown那麼你可能已經將其轉換爲dynamic query