Это безобразное решение, честно говоря, и я действительно не знаю, почему вы хотите, чтобы данные выглядели так. ORDER BY
в предложении OVER
- это полная догадка, ум:
WITH VTE AS(
SELECT *
FROM (VALUES(2000,421,123,145,126),
(2000,422,124,146,127),
(2000,423,125,147,128),
(2000,424,126,148,129),
(2001,425,127,149,130),
(2001,426,128,150,131),
(2001,427,129,151,132),
(2002,428,130,152,133),
(2002,429,131,153,134)) V ([Year], Q1, Q2, Q3, Q4)),
RNs AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [Year] ORDER BY Q1) AS RN --ORDER BY is total guess
FROM VTE)
SELECT RN1.[Year], RN1.Q1, RN1.Q2, RN1.Q3, RN1.Q4,
RN2.[Year], RN2.Q1, RN2.Q2, RN2.Q3, RN2.Q4,
RN3.[Year], RN3.Q1, RN3.Q2, RN3.Q3, RN3.Q4
FROM RNs RN1
LEFT JOIN RNs RN2 ON RN1.[Year] = RN2.[Year] - 1
AND RN1.RN = RN2.RN
LEFT JOIN RNs RN3 ON RN1.[Year] = RN3.[Year] - 2
AND RN1.RN = RN3.RN
WHERE RN1.[Year] = (SELECT MIN(sq.[Year])
FROM RNs sq)
ORDER BY RN1.RN;
Это также не будет работать так, как предполагалось, если через год после того, как у самого младшего будет больше строк, которые будут первыми (например, , если в 2003 году было 5 строк, вы получили бы только 4).
Редактировать: все еще уродливо, но это помогает, когда у вас больше строк:
WITH VTE AS(
SELECT *
FROM (VALUES(2000,421,123,145,126),
(2000,422,124,146,127),
(2000,423,125,147,128),
(2000,424,126,148,129),
(2001,425,127,149,130),
(2001,426,128,150,131),
(2001,427,129,151,132),
(2002,428,130,152,133),
(2002,429,131,153,134),
(2003,429,132,154,135),
(2003,430,133,155,136),
(2003,431,134,156,137),
(2003,432,135,157,138),
(2003,433,136,158,139)) V ([Year], Q1, Q2, Q3, Q4)),
RNs AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [Year] ORDER BY Q1) AS RN --ORDER BY is total guess
FROM VTE),
Tally AS (
SELECT DISTINCT RNs.RN, Y.MinYear
FROM RNs
CROSS APPLY (SELECT MIN(Year) AS MinYear FROM RNs) Y)
SELECT RN1.[Year], RN1.Q1, RN1.Q2, RN1.Q3, RN1.Q4,
RN2.[Year], RN2.Q1, RN2.Q2, RN2.Q3, RN2.Q4,
RN3.[Year], RN3.Q1, RN3.Q2, RN3.Q3, RN3.Q4,
RN4.[Year], RN4.Q1, RN4.Q2, RN4.Q3, RN4.Q4
FROM Tally T
LEFT JOIN RNs RN1 ON T.RN = RN1.RN
AND RN1.[Year] = T.MinYear
LEFT JOIN RNs RN2 ON T.MinYear = RN2.[Year] - 1
AND T.RN = RN2.RN
LEFT JOIN RNs RN3 ON T.MinYear = RN3.[Year] - 2
AND T.RN = RN3.RN
LEFT JOIN RNs RN4 ON T.MinYear = RN4.[Year] - 3
AND T.RN = RN4.RN
ORDER BY T.RN;