2017-10-10 21 views
1

這是我經常選擇查詢:到行列轉換SQL查詢的正確方法

SELECT [category], [price], [company] 
FROM [prices] 
INNER JOIN [company] AS [co] ON [co].[company] = [pr].[company] 
WHERE [co].[id] IN (1,2,3); 

結果是:

category | price | company 
---------+-------+------------- 
Srv  | 1200 | CoA 
Srv  | 2800 | CoB 
EQ  | 5400 | CoA 
Deduc | 400 | CoA 
Deduc | 150 | CoB 

我需要這樣的結果:

PriceASrv | PriceBSrv | PriceAEQ | PriceBEQ | PriceADeduc | PriceBDeduc 
-----------+-----------+----------+----------+-------------+------------- 
1200  | 2800  | 5400  | NULL  | 400   | 150 

看來我需要兩次PIVOT,對嗎?有人有什麼主意嗎?

+1

你有列固定數量的還是動態的? –

+0

您不需要兩次旋轉,但正如您在下面的示例中看到的,您需要連接「公司」和「類別」值。當結果缺失時,它看起來像是需要所有的「類別」和「公司」。你有'公司'表,'公司'和'類別'表有一行,每個類別有一行? – Beth

+0

SQL語言**實際**需要能夠知道在編譯時有多少列和什麼類型,在查詢實際上在任何data_上執行之前。如果你不能做到這一點,你需要通過動態sql(第一步確定「多少列」問題的答案)或者在客戶端代碼中進行調整,分兩步進行。 –

回答

1

不,你不需要轉動兩次,但是你可能需要一個動態查詢,如果:

  1. 可以有兩個以上的公司,還是
  2. 貴公司名稱可以更改或
  3. 您的分類可以更改。

如果這三個條件都是假的,以下兩種查詢將工作:

DECLARE @T TABLE (Category VARCHAR(10), Price INT, Company CHAR(3)); 
INSERT @T VALUES 
    ('Srv', 1200, 'CoA'), 
    ('Srv', 2800, 'CoB'), 
    ('EQ', 5400, 'CoA'), 
    ('Deduc', 400, 'CoA'), 
    ('Deduc', 150, 'CoB'); 

-- With PIVOT 
SELECT * 
FROM (
    SELECT CatCom = 'Price' + RIGHT(Company, 1) + Category, 
      Price 
    FROM @T) AS T 
PIVOT (MAX(Price) FOR CatCom IN ([PriceASrv], [PriceBSrv], [PriceAEQ], [PriceBEQ], [PriceADeduc], [PriceBDeduc])) AS P 

-- With CASE aggregation 
SELECT PriceASrv = MAX(CASE WHEN Category = 'Srv' AND Company = 'CoA' THEN Price END), 
     PriceBSrv = MAX(CASE WHEN Category = 'Srv' AND Company = 'CoB' THEN Price END), 
     PriceAEQ = MAX(CASE WHEN Category = 'EQ' AND Company = 'CoA' THEN Price END), 
     PriceBEQ = MAX(CASE WHEN Category = 'EQ' AND Company = 'CoB' THEN Price END), 
     PriceADeduc = MAX(CASE WHEN Category = 'Deduc' AND Company = 'CoA' THEN Price END), 
     PriceBDeduc = MAX(CASE WHEN Category = 'Deduc' AND Company = 'CoB' THEN Price END) 
FROM @T; 

如果有任何的三個條件都滿足,那麼你可能需要一個動態查詢(這基本上是對上述任何一種查詢進行修改以滿足您的需求)。

1

不,你不需要兩次PIVOT。見下面的查詢。你可以轉換爲動態支點,如果你不知道有多少公司可能存在

Select * from 
(
Select 
    [data]='Price' + RIGHT([company],1) +[category] , 
    [price] 
FROM [prices] 
INNER JOIN [company] as [co] On [co].[company] = [pr].[company] 
WHERE [co].[id] In (1,2,3))src 
PIVOT 
( 
MAX([price]) FOR [data] in (PriceASrv,PriceBSrv,PriceAEQ,PriceBEQ,PriceADeduc,PriceBDeduc) 
)p 

see working demo

+0

考慮到他的'NULL'結果,我認爲他需要的不是'INNER' – Beth

+0

一個'LEFT OUTER JOIN'其實,這是一個有點複雜,因爲他需要所有'公司'與'所有'類''交叉連接',然後'與相關的'價格'左邊外部連接'。 – Beth

+1

@Beth我創建了一個演示並恢復了我的更改。這個INNER JOIN將起作用 – DhruvJoshi