Получать данные в одной строке - PullRequest
1 голос
/ 22 сентября 2011

У меня есть две таблицы PackageDetail и PackageDuration PackageDuration имеет PackageID в качестве внешнего ключа, то есть может иметь несколько записей относительно PackageID

Схема PackageDetail:

PackageID  INT PK
PackageName Nvarchar(50)

Схема таблицы PackageDuration:

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

Таблицы PackageDetail имеют следующие записи:

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 не более этого (если игнорировать это) Теперь я хочу выбрать записи следующим образом:

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

Пожалуйста, подскажите, как мне этого добиться.

Ответы [ 4 ]

5 голосов
/ 22 сентября 2011

Другой подход:

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
1 голос
/ 22 сентября 2011

Это должно работать до тех пор, пока длительности являются уникальными для пакета и равны 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 голосов
/ 22 сентября 2011

Может быть, я что-то упустил в требованиях, но похоже, что PIVOT Sql Server - это то, что вы ищете.

Здесь, на SO * есть довольно много вопросов о PIVOT ... Вот хороший чистый пример со ссылками на другие вопросы: Как преобразовать строки в столбцы в SQL Server 2005

Большим преимуществом сводной таблицы по сравнению с другими ответами здесь является то, что она будет масштабироваться без изменений, если вы добавите записи в вашу таблицу PackageDuration в будущем.

0 голосов
/ 22 сентября 2011
;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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...