2015-07-20 3 views
0

Я видел несколько похожих вопросов, заданных в Stackoverflow с тем же вопросом, но это не подходит ни к одному из них.Строки отображения в виде столбцов

У меня есть 3 стола Покупка, гостиница, покупка автомобилей в отеле и автомобиле - от 1 до 0 или много отношений. MS SQL 2008 Server.

Покупка Таблица

pid bookingdate ... 
1 
2 
3 

Table Hotel

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 

Если для данного идентификатора покупки есть только один отель, другие столбцы должны быть пустыми. Если более 4 отелей игнорируют другие отели (5-й и 6-й векторы)

Пожалуйста, примите, что на этом этапе на столике может быть 0 или 1.

(Advance :: >> Если таблица автомобиля может 0 много (отношений до покупки) 1.) брать только первую запись на счет 2.) получить сумму записей.)

Цели этого проекта сгенерируйте файл csv, который может быть загружен в сторонний продукт. В настоящее время у нас около 100 колонок для покупки и автомобилей около 30 колонок для отеля (всего 130). При отображении строк в гостиницах это будет 220 (100 + 30 x 4) столбцов. И около 100 тыс. Строк. Производительность также является проблемой.

Я пробовал несколько вещей, но ничего успешного не было даже близко к застреванию. 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() или что-то вроде этого 'Select PID, газоразрядных, DENSE_RANK() OVER (ORDER BY ИДП) ИЗ ОТЕЛЯ ГДЕ ПИД-регулятора ( ВЫБОР PID FROM Отель WHERE PID IN (SELECT FROM PID Purchase WHERE rdate BETWEEN '2014-04-01' AND '2014-12-31' ) GROUP BY pid HAVING COUNT (pid)> 1) ' – Udaan

ответ

0

ОК, я нашел решение. Вы можете уточнить и добавить свои мысли. Динамическое имя столбцов было бы удобно. (Т.е. product1, product2, product3, product4)

Схема

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

, если Количество столбцов не меняется, вы можете использовать Pivot/UNPIVOT

Вот статья, которая 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

Смежные вопросы