次のようなSQLデータベーステーブルがあります。
Day Period Subject
Mon 1 Ch
Mon 2 Ph
Mon 3 Mth
Mon 4 CS
Mon 5 Lab1
Mon 6 Lab2
Mon 7 Lab3
Tue 1 Ph
Tue 2 Ele
Tue 3 Hu
Tue 4 Ph
Tue 5 En
Tue 6 CS2
Tue 7 Mth
次のように表示したい:クロス集計またはピボットの種類
Day P1 P2 P3 P4 P5 P6 P7
Mon Ch Ph Mth CS2 Lab1 Lab2 Lab3
Tue Ph Ele Hu Ph En CS2 Mth
それを行うための理想的な方法は何でしょうか?誰かが私にSQLコードを見せてくださいませんか?
おそらくPIVOT機能でそれを行うことができますが、私は古い学校の方法が好きです:
SELECT
dy,
MAX(CASE WHEN period = 1 THEN subj ELSE NULL END) AS P1,
MAX(CASE WHEN period = 2 THEN subj ELSE NULL END) AS P2,
MAX(CASE WHEN period = 3 THEN subj ELSE NULL END) AS P3,
MAX(CASE WHEN period = 4 THEN subj ELSE NULL END) AS P4,
MAX(CASE WHEN period = 5 THEN subj ELSE NULL END) AS P5,
MAX(CASE WHEN period = 6 THEN subj ELSE NULL END) AS P6,
MAX(CASE WHEN period = 7 THEN subj ELSE NULL END) AS P7
FROM
Classes
GROUP BY
dy
ORDER BY
CASE dy
WHEN 'Mon' THEN 1
WHEN 'Tue' THEN 2
WHEN 'Wed' THEN 3
WHEN 'Thu' THEN 4
WHEN 'Fri' THEN 5
WHEN 'Sat' THEN 6
WHEN 'Sun' THEN 7
ELSE 8
END
新しい学校の方法が必要な場合に備えてください。 (PivotステートメントはSQL2005 +で機能するはずです。サンプルデータのみの場合はVALUES
ビットのみSQL2008)
WITH ExampleData AS
(
SELECT X.*
FROM (VALUES
('Mon', 1, 'Ch'),
('Mon', 2, 'Ph'),
('Mon', 3, 'Mth'),
('Mon', 4, 'CS'),
('Mon', 5, 'Lab1'),
('Mon', 6, 'Lab2'),
('Mon', 7, 'Lab3'),
('Tue', 1, 'Ph'),
('Tue', 2, 'Ele'),
('Tue', 3, 'Hu'),
('Tue', 4, 'Ph'),
('Tue', 5, 'En'),
('Tue', 6, 'CS2'),
('Tue', 7, 'Mth')
) AS X (Day, Period, Subject)
)
SELECT Day, [1] AS P1, [2] AS P2,[3] AS P3, [4] AS P4, [5] AS P5,[6] AS P6,[7] AS P7
FROM ExampleData
PIVOT
(
Max(Subject)
FOR Period IN ([1], [2],[3],[4], [5],[6], [7])
) AS PivotTable;
結果
Day P1 P2 P3 P4 P5 P6 P7
---- ---- ---- ---- ---- ---- ---- ----
Mon Ch Ph Mth CS Lab1 Lab2 Lab3
Tue Ph Ele Hu Ph En CS2 Mth
試すことができます...
SELECT DISTINCT Day,
(SELECT Subject
FROM my_table mt2
WHERE mt2.Day = mt.Day AND
Period = 1) AS P1,
(SELECT Subject
FROM my_table mt2
WHERE mt2.Day = mt.Day AND
Period = 2) AS P2,
.
.
etc
.
.
.
(SELECT Subject
FROM my_table mt2
WHERE mt2.Day = mt.Day AND
Period = 7) AS P7
FROM my_table mt;
でも私はそれがとても好きだとは言えませんしかし、何もないよりはましだ.
クロスアプライを使用して、単一の列にコンマ区切り形式のすべての値を取得します。 「7」の異なる列の代わりに。次のクエリは、任意の列->行マッピングに使用できます
SELECT DISTINCT Day, [DerivedColumn] FROM <Table> A CROSS APPLY ( SELECT Period + ',' FROM <Table> B WHERE A.Day = B.Day Order By Period FOR XML PATH('') ) AS C (DerivedColumn)
Monなどの1つの列に[Ch、Ph、Mth、CS2、Lab1、Lab2、Lab3]が表示されます。これを特定の日を照会するテーブルとして使用できます。
お役に立てれば
DECLARE @TIMETABLE TABLE (
[Day] CHAR(3),
[Period] TINYINT,
[Subject] CHAR(5)
)
INSERT INTO @TIMETABLE([Day], [Period], [Subject])
VALUES
('Mon', 1, 'Ch'),
('Mon', 2, 'Ph'),
('Mon', 3, 'Mth'),
('Mon', 4, 'CS'),
('Mon', 5, 'Lab1'),
('Mon', 6, 'Lab2'),
('Mon', 7, 'Lab3'),
('Tue', 1, 'Ph'),
('Tue', 2, 'Ele'),
('Tue', 3, 'Hu'),
('Tue', 4, 'Ph'),
('Tue', 5, 'En'),
('Tue', 6, 'CS2'),
('Tue', 7, 'Mth')
SELECT
[Day],
MAX(CASE [Period] WHEN 1 THEN [Subject] END) AS P1,
MAX(CASE [Period] WHEN 2 THEN [Subject] END) AS P2,
MAX(CASE [Period] WHEN 3 THEN [Subject] END) AS P3,
MAX(CASE [Period] WHEN 4 THEN [Subject] END) AS P4,
MAX(CASE [Period] WHEN 5 THEN [Subject] END) AS P5,
MAX(CASE [Period] WHEN 6 THEN [Subject] END) AS P6,
MAX(CASE [Period] WHEN 7 THEN [Subject] END) AS P7
FROM @TIMETABLE
GROUP BY [Day]
with pivot_data as
(
select [day], -- groping column
period, -- spreading column
subject -- aggreate column
from pivot_tb
)
select [day], [1] AS P1, [2] AS P2,[3] AS P3, [4] AS P4, [5] AS P5,[6] AS P6,[7] AS P7
from pivot_data
pivot ( max(subject) for period in ([1], [2],[3],[4], [5],[6], [7]) ) as p;