2015-07-20 121 views
0

我曾在Stackoverflow上看到過幾個類似的問題,但是這並不適合所有這些問題。將行顯示爲列

我有3個表購買,酒店,汽車購買酒店和汽車是1比0或許多關係。 MS SQL 2008服務器。

採購表

pid bookingdate ... 
1 
2 
3 

酒店表

hid pid amount rooms location brand... 
1 1 
2 1 
3 1 
4 3 
4 3 

車表

cid pid make model ... 
1 1 
2 2 
3 2 

我要的是顯示在列的酒店數據

pid bookingdate cid make model hid1 amount1 rooms1 location1 brand1 hid2 amount2 rooms2 location2 brand2 hid3 amount3 rooms3 location3 brand3 hid4 amount4 rooms4 location4 brand4 

如果給定購買ID只有一家酒店,則其他列應爲空。如果超過4家酒店忽略其他酒店(第六第六等)

請假設車臺在這個階段可以有0或1。

(提前:: >>如果汽車能表0到很多(關係購買)1)只取第一條記錄佔2)獲得記錄的總和。)

目的本項目是生成一個可以上傳到某個第三方產品的csv文件。目前,我們有大約100列購買和汽車約30列酒店(130全部)。隨着酒店行以這種方式顯示,它將是220(100 + 30 x 4)列。約100K行。性能也是一個問題。

我嘗試了一些東西,但沒有成功,甚至沒有接近卡住。 This是我得到的最接近的,但我有30列複製不只是一個,事實上,我有一種感覺,PIVOT是不是要走的路。我使用DENSE_RANK()或類似的

SELECT pid 
, hid 
, DENSE_RANK() OVER(ORDER BY pid) 
FROM HOTEL 
WHERE pid IN ( 
       SELECT pid 
       FROM Hotel 
       WHERE pid IN (
          SELECT pid 
          FROM Purchase 
          WHERE rdate BETWEEN '2014-04-01' AND '2014-12-31' 
          ) 
       GROUP BY pid 
       HAVING COUNT(pid) > 1 
      ) 

假設那麼我們可能能夠與附着在一起的第一購買超過1處理酒店,使用光標(醜陋的)或類似的東西

+0

你試過了什麼?你可以向你展示查詢和你在哪堆棧? – Fabio

+0

我嘗試了一些東西,但沒有成功,甚至沒有接近卡住。 http://sqlfiddle.com/#!3/832f1/16是我得到的最接近的,但我有30列複製不只是一個,事實上,我有一種感覺,PIVOT是不是要走的路。我使用DENSE_RANK()或類似的東西'選擇PID OVER(ORDER BY PID) 思考,HID,DENSE_RANK()從酒店 WHERE PID IN(SELECT PID從酒店 其中PID IN(SELECT PID自購買WHERE rdate BETWEEN'2014-04-01'和'2014-12-31' ) GROUP BY pid HAVING COUNT(pid)> 1)' – Udaan

回答

0

好吧我找到了解決方案。歡迎您完善並添加您的想法。動態命名列會很方便。 (即產品1,產品2,產品3,產品4)

架構

create table Purchase 
(
    pid int, 
    purchasedate date, 
    currency varchar(10), 
    paymenttype varchar(10), 
    creditcard varchar(10), 
    creditcardtype varchar(10) 
); 

create table Hotel 
(
    hid int, 
    pid int, 
    product varchar(30), 
    country varchar(10), 
    city varchar(10), 
    rooms int, 
    starrating int 
); 

create table Car 
(
    cid int, 
    pid int, 
    product varchar(30), 
    country varchar(10), 
    city varchar(10), 
    cancel int, 
    starrating int 
); 


insert into Purchase values (1, '2015-01-15','AUD', 'CC','12345678','AMEX') 
insert into Purchase values (2, '2015-01-15','AUD', 'CC','12345678','AMEX') 
insert into Purchase values (3, '2015-01-15','AUD', 'CC','12345678','AMEX') 
insert into Purchase values (4, '2015-01-15','AUD', 'CC','12345678','AMEX') 
insert into Purchase values (5, '2015-01-15','AUD', 'CC','12345678','AMEX') 


insert into Hotel values (1,1, 'Five for Two','Australia', 'Melbourne','1','3') 
insert into Hotel values (2,1, 'Five for None','Australia', 'Sydney','1','3') 
insert into Hotel values (3,1, 'Five for Five','Australia', 'Melbourne','1','3') 
insert into Hotel values (4,1, 'Five for Two','Australia', 'Jamboora','1','3') 
insert into Hotel values (5,2, 'Five for Three','Australia', 'Sydney','1','3') 
insert into Hotel values (6,2, 'Five for Love','Australia', 'Cook','1','3') 
insert into Hotel values (7,2, 'Five for Grease','Australia', 'Darwin','1','3') 
insert into Hotel values (8,3, 'Love Me','Australia', 'Darwin','1','3') 
insert into Hotel values (9,4, 'Live for Grease','Australia', 'Footscray','1','3') 
insert into Hotel values (10,4, 'Love Grease','Australia', 'Officer','1','3') 

insert into Car values (1,1, 'Love Grease','Australia', 'Officer','1','3') 
insert into Car values (2,2, 'Love Grease','Australia', 'Cook','1','3') 
insert into Car values (3,4, 'Live Grease','Australia', 'Jamboora','1','3') 
-- For Advance insert into Car values (4,4, 'Cove Grease','Australia', 'Melbourne','1','3') 

而且代碼

SELECT *, DENSE_RANK() OVER(PARTITION BY pid ORDER BY hid DESC) AS Ranking 
INTO #TempHotel 
FROM Hotel 

SELECT P.pid, P.purchasedate, P.currency, P.paymenttype, P.creditcard, P.creditcardtype 
    ,C.cid, C.product, C.country, C.city, C.cancel, C.starrating 
    ,H1.hid, H1.product, H1.country, H1.city,H1.rooms,H1.starrating 
    ,H2.hid, H2.product, H2.country, H2.city,H2.rooms,H2.starrating 
    ,H3.hid, H3.product, H3.country, H3.city,H3.rooms,H3.starrating 
    ,H4.hid, H4.product, H4.country, H4.city,H4.rooms,H4.starrating 
FROM Purchase P 
left join Car C on P.pid = C.pid 
left join #TempHotel H1 on P.pid = H1.pid and H1.Ranking = 1 
left join #TempHotel H2 on P.pid = H2.pid and H2.Ranking = 2 
left join #TempHotel H3 on P.pid = H3.pid and H3.Ranking = 3 
left join #TempHotel H4 on P.pid = H4.pid and H4.Ranking = 4 
DROP Table #TempHotel 

您還可以在SQL小提琴Here找到。

-1

如果想的東西列數永遠不會改變,你可以使用數據透視/逆透視

這裏是一個TechNet文章它說明了一切:http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

,並從文章的樣本。

-- Pivot table with one row and five columns 
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days, 
[0], [1], [2], [3], [4] 
FROM 
(SELECT DaysToManufacture, StandardCost 
    FROM Production.Product) AS SourceTable 
PIVOT 
(
AVG(StandardCost) 
FOR DaysToManufacture IN ([0], [1], [2], [3], [4]) 
) AS PivotTable; 
+0

對投票的解釋將不勝感激。 – Wombelite

+0

我不需要平均或總和。我之前看過這個解決方案。我不確定我們是否可以在這種情況下使用PIVOT,順便說一句,我沒有把它標出來 – Udaan