Stimme völlig mit @Joe C (+1) überein, "rohe Gewalt" ist der einfachste Weg. Nur weil ich die Übung gemacht habe, den Unpivot dafür zu bauen, aus keinem anderen Grund, als die Einfachheit der großen Fallaussage zu rechtfertigen. (Außerdem ist es viel einfacher, mit der „keine Daten“ Situation befassen sich mit dem großen Fall-Anweisung.)
Zunächst gründen einige Daten Beispiel:
--DROP TABLE MyTable
GO
CREATE TABLE MyTable
(
CUSIPNumber varchar(20) not null
,Year smallint not null
,Rate1 float not null
,Rate2 float not null
,Rate3 float not null
,Rate4 float not null
,Rate5 float not null
,Rate6 float not null
,Rate7 float not null
,Rate8 float not null
,Rate9 float not null
,Rate10 float not null
,Rate11 float not null
,Rate12 float not null
,Rate13 float not null
,Rate14 float not null
,Rate15 float not null
)
INSERT MyTable values
('001383EA2', 16, 4.0505, 4.0510, 4.0515, 4.0520, 4.0525, 4.0530, 4.0535, 4.0550, 4.0545, 4.0550, 4.0560, 4.0570, 4.0575, 4.0585, 0)
,('001383EA2', 15, 3.0505, 3.0510, 3.0515, 3.0520, 3.0525, 3.0530, 3.0535, 3.0550, 3.0545, 3.0550, 3.0560, 3.0570, 3.0575, 3.0585, 3.0599)
,('001383__1', 01, 1.1, 2.2, 3.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
,('001383_NoData', 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-- What we have
SELECT *
from MyTable
Hier ist die grundlegende Entpivotisierung Aussage. Spalten sind aliased/umbenannt, für max() zu ermöglichen, die neuesten Artikel zu identifizieren (rate2 ist> Rate11 ...)
-- Build the unpivot statement
SELECT *
from (select CUSIPNumber, Year, Rate1, Rate3, Rate4, Rate5, Rate6, Rate7, Rate8, Rate9, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15
from MyTable) src
unpivot (RateValue
for RateNumber in (Rate1, Rate3, Rate4, Rate5, Rate6, Rate7, Rate8, Rate9, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15)
) unpvt
-- Whoops! Alias the "Rate" columns, so that they can be sorted
SELECT *
from (select
CUSIPNumber
,Year
,Rate1 Rate01
,Rate2 Rate02
,Rate3 Rate03
,Rate4 Rate04
,Rate5 Rate05
,Rate6 Rate06
,Rate7 Rate07
,Rate8 Rate08
,Rate9 Rate09
,Rate10
,Rate11
,Rate12
,Rate13
,Rate14
,Rate15
from MyTable) src
unpivot (RateValue
for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15)
) unpvt
Diese Daten müssen mehrmals referenziert werden. Einfachste Weg, dies zu tun, ist es ein CTE zu machen:
-- Make it a Common Table Expression
WITH ctePvt
as (select CUSIPNumber, Year, RateNumber, RateValue
from (select
CUSIPNumber
,Year
,Rate1 Rate01
,Rate2 Rate02
,Rate3 Rate03
,Rate4 Rate04
,Rate5 Rate05
,Rate6 Rate06
,Rate7 Rate07
,Rate8 Rate08
,Rate9 Rate09
,Rate10
,Rate11
,Rate12
,Rate13
,Rate14
,Rate15
from MyTable) src
unpivot (RateValue
for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15)
) unpvt)
select *
from ctePvt
Damit können wir die neueste Rate
-- This determines the most recent rate
WITH ctePvt
as (select CUSIPNumber, Year, RateNumber, RateValue
from (select
CUSIPNumber
,Year
,Rate1 Rate01
,Rate2 Rate02
,Rate3 Rate03
,Rate4 Rate04
,Rate5 Rate05
,Rate6 Rate06
,Rate7 Rate07
,Rate8 Rate08
,Rate9 Rate09
,Rate10
,Rate11
,Rate12
,Rate13
,Rate14
,Rate15
from MyTable) src
unpivot (RateValue
for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15)
) unpvt)
select
CUSIPNumber
,Year
,max(RateNumber) CurrentRate
from ctePvt
where RateValue <> 0
group by
CUSIPNumber
,Year
Und damit bestimmen, können wir schließlich den Wert erhalten für die letzten bewerten
-- This gest the values for the most recent rate
WITH ctePvt
as (select CUSIPNumber, Year, RateNumber, RateValue
from (select
CUSIPNumber
,Year
,Rate1 Rate01
,Rate2 Rate02
,Rate3 Rate03
,Rate4 Rate04
,Rate5 Rate05
,Rate6 Rate06
,Rate7 Rate07
,Rate8 Rate08
,Rate9 Rate09
,Rate10
,Rate11
,Rate12
,Rate13
,Rate14
,Rate15
from MyTable) src
unpivot (RateValue
for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15)
) unpvt)
select
cteBase.CUSIPNumber
,cteBase.Year
,cteBase.RateValue
from ctePvt cteBase
inner join (-- Most recent rate per item
select
CUSIPNumber
,Year
,max(RateNumber) CurrentRate
from ctePvt
where RateValue <> 0
group by
CUSIPNumber
,Year) cteRecent
on cteRecent.CUSIPNumber = cteBase.CUSIPNumber
and cteRecent.Year = cteBase.Year
and cteRecent.CurrentRate = cteBase.RateNumber
Beachten Sie, dass dies keine Zeile für die Position zurückkehrt, wo es keine Geschwindigkeitswerte. Es gibt eine Handvoll Wege, die gelöst werden können, aber genug.
Sind Sie nicht froh, dass Sie mit der großen Fallaussage gegangen sind?
Die Normalisierung des Datenbankschemas wäre ideal. – HardCode
Rechts. Ich bin ein SSRS Report Writer und kann nur verwenden, was zur Verfügung gestellt wird. Versuche es zum Laufen zu bringen. Der SQL-Entwickler kann die Daten nicht normalisieren. -sigh- – BIReportGuy
können Sie erklären, wie das funktioniert? definiere "spätestes" .... jedes Jahr nach dem letzten ist 0? in diesem Fall nach 'Rate14' wäre 0? –