Frage

Ich habe eine Tabelle, wie unten

Rate Effective_Date
---- --------------
5.6  02/02/2009
5.8  05/01/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

Ich soll die Zimmer finden, die für das aktuelle Datum wirksam sind und danach. So die aktuelle effektive Rate zu erhalten, verwende ich

SELECT TOP 1 * from table 
where effective_date < '05/05/2009' 
order by effective date desc

für die Preise nach dem aktuellen Datum der Abfrage

SELECT * from table 
where effective_date > '05/05/2009'

So kombinieren Sie diese beiden Ergebnis i verwenden, um eine Vereinigung wie

SELECT TOP 1 * from table 
where effective_date < '05/05/2009' 
order by effective date desc

UNION

SELECT * from table 
where effective_date > '05/05/2009'

Das erwartete Ergebnis ist

Rate Effective Date
---- --------------
5.8  05/01/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

Aber ich bekomme das tatsächliche Ergebnis als

Rate Effective Date
---- --------------
5.6  02/02/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

Ich habe keine Ahnung, warum dies geschieht? Irgendwelche Vorschläge?

War es hilfreich?

Lösung

Es funktioniert so:

select *
from (
    select top 1 *
    from table
    where effective_date <= '05/05/2009'
    order by effective_date desc
) as current_rate

union all

select *
from table
where effective_date > '05/05/2009'

Andere Tipps

Die Sortierung nach in einer select-Anweisung, den Teil einer Vereinigung ist, wird ignoriert. Daher Ihr TOP 1 ist ein willkürlichen Rekord (wahrscheinlich der erste Datensatz durch die gruppierten Schlüssel für die Tabelle) auswählen.

Order By ist ungültig, wenn es mit einer Union verwendet ...

Ich arbeitete einen Quickie und schmutzig Dingen mit Common Table Expression mit einem gewissen Rang und Case-Anweisung Tricks auf, um die Ergebnisse, die Sie für .. suchen

WITH CTE_RATES ( RATE, EFFECTIVE_DATE, CUR, SORT )
AS (
    SELECT 
        Rate,
        Effective_date,
        CASE WHEN Effective_date > '5/5/2009' THEN 1
             ELSE 0
        END,
        RANK() OVER (PARTITION BY
                         CASE WHEN EFFECTIVE_DATE > '5/5/2009' THEN 1
                              ELSE 0
                         END
                     ORDER BY EFFECTIVE_DATE DESC)
    FROM TestTable
)

SELECT RATE, EFFECTIVE_DATE
FROM (
    SELECT RATE, EFFECTIVE_DATE 
    FROM CTE_RATES 
    WHERE CUR = 0 AND SORT = 1

    UNION ALL

    SELECT RATE, EFFECTIVE_DATE
    FROM CTE_RATES
    WHERE CUR = 1
    ) AS QRY
ORDER BY EFFECTIVE_DATE

Um zu erklären, was passiert ist ...

Der CTE definiert die Rate, Datum, aktuelle und Sortier-Flags aus der Abfrage zurückgegeben ...

Die CASE trennt die Ergebnisse in denjenigen, die mit dem Datum der gewünschten Daten vor sind, und die, die nach dem Datum der gewünschten Daten sind .. Wir nutzen die Ergebnisse aus dem Gehäuse (CUR) in unserer Vereinigung, die Ergebnisse aus der partitionierten Liste zu ziehen. .

Der Rang () Funktion sortiert dann die Liste durch eine Partition auf den gleichen Kriterien zu schaffen, die CASE-Anweisung verwendet die Liste zu trennen .. dann sind wir durch den Zeitpunkt des Inkrafttretens bestellen Mode in absteigender Reihenfolge. Dies wird die „Vergangenheit“ Liste nehmen und machen es die meisten aktuellen „Vergangenheit“ -Eintrag Rang 1 ..

Dann in der Union Teil der Abfrage ..

Im oberen Teil sind wir den Rang und das Datum aus der „Vergangenheit“ -Liste (Aktuell = 0) und den ersten Eintrag in der „Vergangenheit“ Liste bekommen .. (sort = 1) .. das gibt 1 zurück Datensatz (oder 0, wenn es keine Aufzeichnungen gibt, die zum Datum der gewünschten Daten vor) sind ..

Dann wir Gewerkschaft, dass mit all dem Datensatz aus der „aktuellen“ Liste (Aktuell = 1)

Dann endlich .. nehmen wir die Ergebnisse der UNION .. und damit uns alle aktuellen Datensätze nach dem Wirksamwerden zu geben, und der „aktuelle“ bisherige Rekord.

Ich glaube, die obigen Abfragen 05.01.2009 werden ausschließlich unter Verwendung von anstelle von <= und> =.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top