2011-09-22 16 views
1

我有兩個表PackageDetail和PackageDuration PackageDuration有包標識爲外鍵即可以具有的與多個記錄包標識獲取數據

的PackageDetail的模式是:

PackageID INT PK 
PackageName Nvarchar(50) 
在PackageDuration表

模式是:

DurationID INT PK 
Price Money 
Duration Nvarchar(50) 
PackageID INT FPK 

PackageDetail表有follwoing記錄:

PackageID  PackageName 
    1    TestPackage 
    2    MySecondPackage 

PackageDuration表有以下記錄:

DurationID  PackageID Price  Duration 
    1     1  100   6 
    2     1  200   12 
    3     1  300   24 
    4     2  500   6 

PackageDuration表可以有最多3條記錄與一個包標識不比這更多的(如果有忽略) 現在我要選擇的記錄作爲以下方式:

PackageId PackageNAme  Price1 Price2 Price3 Duration1 Duration2 Duration3 
1   TestPackage  100 200 300   6   12   24 
2   MySecondPackage 500 null null   6  null   null 

請建議我如何完成此操作。

+0

如果PackageID 1有4個價格怎麼辦?您是否需要爲Price4和Duration4動態添加列? –

+0

是的,一個套餐可以根據持續時間6月,12(1年),24(2年)最大3價格 – Askiitians

回答

5

另一種方法:

WITH Durations AS 
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY PackageId ORDER BY DurationId) Sequence 
    FROM PackageDuration 
) 

SELECT A.PackageId, B.PackageName, 
     MIN(CASE WHEN Sequence = 1 THEN Price ELSE NULL END) Price1, 
     MIN(CASE WHEN Sequence = 2 THEN Price ELSE NULL END) Price2, 
     MIN(CASE WHEN Sequence = 3 THEN Price ELSE NULL END) Price3, 
     MIN(CASE WHEN Sequence = 1 THEN Duration ELSE NULL END) Duration1, 
     MIN(CASE WHEN Sequence = 2 THEN Duration ELSE NULL END) Duration2, 
     MIN(CASE WHEN Sequence = 3 THEN Duration ELSE NULL END) Duration3 
FROM Durations A 
INNER JOIN PackageDetail B 
ON A.PackageId = B.PackageId 
GROUP BY A.PackageId, B.PackageName 
+0

+1我最喜歡這個,因爲沒有硬編碼值。你知道,(需求)常量可能會隨時間而改變......從現在開始一年:「你知道,我們應該改變持續時間值,那些定義在哪裏?」 –

1

這應該工作,只要持續時間是一個包獨特的,他們要麼是6,12,或24

SELECT 
    PackageDetail.PackageId, PackageDetail.PackageName, 
    D1.Price as Price1, D2.Price as Price2, D3.Price as Price3, 
    D1.Duration as Duration1, D2.Duration as Duration2, D3.Duration as Duration3 
FROM PackageDetail 
LEFT OUTER JOIN PackageDuration D1 
    ON D1.PackageId = PackageDetail.PackageId AND D1.Duration = 6 
LEFT OUTER JOIN PackageDuration D2 
    ON D2.PackageId = PackageDetail.PackageId AND D2.Duration = 12 
LEFT OUTER JOIN PackageDuration D3 
    ON D3.PackageId = PackageDetail.PackageId AND D3.Duration = 24 
0
;WITH pvt AS 
(
    SELECT PackageID, 
     Price1 = MAX(CASE WHEN Duration = 6 THEN Price END), 
     Price2 = MAX(CASE WHEN Duration = 12 THEN Price END), 
     Price3 = MAX(CASE WHEN Duration = 24 THEN Price END), 
     Duration1 = MAX(CASE WHEN Duration = 6 THEN 6 END), 
     Duration2 = MAX(CASE WHEN Duration = 12 THEN 12 END), 
     Duration3 = MAX(CASE WHEN Duration = 24 THEN 24 END) 
    FROM dbo.PackageDuration 
    GROUP BY PackageID 
) 
SELECT 
    pvt.PackageID, 
    p.PackageName, 
    pvt.Price1, pvt.Price2, pvt.Price3, 
    pvt.Duration1, pvt.Duration2, pvt.Duration3 
FROM 
    dbo.PackageDetail AS p 
INNER JOIN 
    pvt ON p.PackageID = pvt.PackageID 
ORDER BY p.PackageID; 
0

也許我在需求中缺少一些東西,但它似乎像Sql Server的PIVOT是你正在尋找的東西。

quite a few questions here at SO約PIVOT ...以下是與其他問題時引用了良好清晰的例子:How do i transform rows into columns in sql server 2005

在這裏其他的答案透視表的一大好處是,它會向外擴展,沒有修改,如果您將記錄添加到您未來的PackageDuration表中。

+0

我開始在使用PIVOT的解決方案上工作,但有一些問題需要輸出,這會使PIVOT比必要更復雜。如果只需要前4列,使用PIVOT編寫將會更加直觀。 –