web-dev-qa-db-ja.com

T-SQLでピボットする方法

解決できない質問があります。

私のクエリは:

SELECT
    f.Title, p.StartOfShowing
FROM  
    PlayDates p 
INNER JOIN 
    PlayDateSections ps ON p.PlayDateId = ps.PlayDateId
INNER JOIN 
    Films f ON p.FilmId = f.FilmId
WHERE  
    DATEDIFF(d, p.StartOfShowing, '2018-04-30') = 0

テーブルの結果は次のようになります。

A Quiet Place                      2018-04-30 12:40
A Quiet Place                      2018-04-30 15:05
A Quiet Place                      2018-04-30 17:30
A Quiet Place                      2018-04-30 19:55
A Quiet Place                      2018-04-30 22:20
Avengers : Infinity War            2018-04-30 11:10
Avengers : Infinity War            2018-04-30 11:30
Avengers : Infinity War            2018-04-30 12:00
Avengers : Infinity War            2018-04-30 13:00
Avengers : Infinity War            2018-04-30 13:20
Avengers : Infinity War            2018-04-30 14:00
Avengers : Infinity War            2018-04-30 14:20
Avengers : Infinity War            2018-04-30 14:40
Avengers : Infinity War            2018-04-30 15:10
Avengers : Infinity War            2018-04-30 16:10
Avengers : Infinity War            2018-04-30 16:30
Avengers : Infinity War            2018-04-30 17:10
Avengers : Infinity War            2018-04-30 17:30
Avengers : Infinity War            2018-04-30 17:50
Avengers : Infinity War            2018-04-30 18:20
Avengers : Infinity War            2018-04-30 19:20
Avengers : Infinity War            2018-04-30 19:40
Avengers : Infinity War            2018-04-30 20:20
Avengers : Infinity War            2018-04-30 20:40
Avengers : Infinity War            2018-04-30 21:00
Avengers : Infinity War            2018-04-30 21:30
Avengers : Infinity War            2018-04-30 22:50
Avengers : Infinity War  ATMOS     2018-04-30 12:40
Avengers : Infinity War  ATMOS     2018-04-30 15:50
Avengers : Infinity War  ATMOS     2018-04-30 19:00
Avengers : Infinity War  ATMOS     2018-04-30 22:10
Avengers : Infinity War  PLATINUM  2018-04-30 14:40
Avengers : Infinity War  PLATINUM  2018-04-30 17:50
Avengers : Infinity War  PLATINUM  2018-04-30 21:00
Avengers : Infinity War  PLATINUM  2018-04-30 23:30
Love Simon                         2018-04-30 14:25
Love Simon                         2018-04-30 19:15
Rampage                            2018-04-30 16:55
Rampage                            2018-04-30 21:45

ただし、以下のような結果を含むピボットクエリが必要でした。

A Quiet Place                     4/30/2018  12:40  15:05  17:30  19:55  22:20
Avengers : Infinity War           4/30/2018  11:10  11:30  12:00  13:00  13:20
Avengers : Infinity War           4/30/2018  14:00  14:20  14:40  15:10  16:10
Avengers : Infinity War           4/30/2018  16:30  17:10  17:30  17:50  18:20
Avengers : Infinity War           4/30/2018  19:20  19:40  20:20  20:40  21:00
Avengers : Infinity War ATMOS     4/30/2018  12:40  15:50  19:00  22:10  NULL
Avengers : Infinity War PLATINUM  4/30/2018  23:30  14:40  17:50  21:00  NULL
Love Simon                        4/30/2018  19:15  14:25  NULL   NULL   NULL
Rampage                           4/30/2018  16:55  21:45  NULL   NULL   NULL
6
Tsuna Sawada

データセットに行番号(ROW_NUMBER)を追加しました。このフィールドは5で除算され(出力には5列が必要です)、この除算の残りと穴番号がフィールドinRows、inColumnsに保持されます。これに基づいて、ピボットを行います。

5で除算し、rest = 0とする特別なケースがあります。このため、私はユースケース...

,RN / 5 + CASE WHEN RN % 5 = 0 THEN -1 ELSE 0 END AS inRows

,CASE WHEN RN % 5 = 0 THEN 5 ELSE RN % 5 END AS inCols

;WITH myCTE AS
(
SELECT
  Title,StartOfShowing
  ,ROW_NUMBER() OVER(PARTITION BY Title ORDER BY StartOfShowing ASC) AS RN
FROM
  tblResults
)
, myPivotSource AS 
(
SELECT Title,StartOfShowing
   --,RN
   --,(RN - 1 )/ 5  AS inRows
   ,RN / 5 + CASE WHEN RN % 5  = 0 THEN -1   ELSE 0  END AS inRows
   ,CASE WHEN RN % 5  = 0 THEN 5 ELSE RN % 5 END AS inCols
FROM
   myCTE
)

SELECT Title
    , CONVERT(varchar(10),[1],101) As dateofShowing 
    , CONVERT(varchar(5),[1],108) AS [1]
    , CONVERT(varchar(5),[2],108) AS [2]
    , CONVERT(varchar(5),[3],108) AS [3]
    , CONVERT(varchar(5),[4],108) AS [4]
    , CONVERT(varchar(5),[5],108) AS [5]
FROM 
   myPivotSource AS PS
   PIVOT 
   (
      MIN(StartOfShowing) FOR inCols IN ([1], [2], [3], [4], [5])
   )PV
ORDER BY Title, inRows

それの出力:

Title                               dateofShowing   1       2       3       4       5
A Quiet Place                       04/30/2018      12:40   15:05   17:30   19:55   22:20
Avengers : Infinity War             04/30/2018      11:10   11:30   12:00   13:00   13:20
Avengers : Infinity War             04/30/2018      14:00   14:20   14:40   15:10   16:10
Avengers : Infinity War             04/30/2018      16:30   17:10   17:30   17:50   18:20
Avengers : Infinity War             04/30/2018      19:20   19:40   20:20   20:40   21:00
Avengers : Infinity War             04/30/2018      21:30   22:50   null    null    null
Avengers : Infinity War  ATMOS      04/30/2018      12:40   15:50   19:00   22:10   null
Avengers : Infinity War  PLATINUM   04/30/2018      14:40   17:50   21:00   23:30   null
Love Simon                          04/30/2018      14:25   19:15   null    null    null
Rampage                             04/30/2018      16:55   21:45   null    null    null

dbfiddle

14
Sabin Bio