将列显示为列

时间:2015-07-20 02:29:30

标签: sql-server sql-server-2008

我在Stackoverflow上看到几个类似的问题与同一主题有关,但这并不符合其中任何一个。

我有3张桌子购买,酒店,汽车购买到酒店和汽车是1到0或许多关系。 MS SQL 2008 Server。

购买表

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家酒店忽略其他酒店(第5区等)

请假设Car table在此阶段可以有0或1。

(Advance ::>>如果Car表可以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附加到购买的酒店

2 个答案:

答案 0 :(得分: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 :(得分:-1)

如果列数永远不会改变,您可以使用Pivot / Unpivot

这是一篇全文的文章:http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

和文章中的一个样本。

cout