2 Stimmen

TSQL ungültige WHERE-Klausel in der Unterabfrage

Ich stehe vor der Situation, dass ich den aktuellen und vorherigen Bestellbetrag in einer einzigen Zeile mithilfe eines SELECT-Statements auswählen muss.

Bestelltabelle:

Kunden-ID
Bestell-ID
Bestelldatum
Bestellbetrag

Aktuelles SELECT-Statement:

SELECT o.OrderId, o.OrderDate, o.OrderAmount, po.OrderAmount
FROM Order o
LEFT JOIN (
   SELECT TOP(1) so.OrderAmount
   FROM Order so
   WHERE so.CustomerId = o.CustomerId and so.OrderId <> o.OrderId
   ORDER BY so.OrderDate DESC
   ) po

Das Problem ist, dass die "WHERE"-Klausel in der Unterabfrage nicht erlaubt ist. Gibt es eine andere Methode, um diese Informationen zu erhalten?

Das ist tatsächlich eine Vereinfachung eines komplexeren SELECT (für eine Ansicht), der Daten für Finanzberichte für den aktuellen und vorherigen Berichtszeitraum erfordert.

8voto

Martin Smith Punkte 417623

Sie benötigen hier OUTER APPLY.

Ihre WHERE-Klausel sieht jedoch nicht richtig aus. Ich gehe davon aus, dass OrderDate unten eindeutig ist, um die "vorherige" Zeile bestimmen zu können.

SELECT o.OrderId,
       o.OrderDate,
       o.OrderAmount,
       po.OrderAmount
FROM   [Order] o
       OUTER APPLY(SELECT TOP(1) so.OrderAmount
                   FROM   [Order] so
                   WHERE  so.CustomerId = o.CustomerId
                          AND so.OrderDate < o.OrderDate
                   ORDER  BY so.OrderDate DESC) po  

Aber es ist möglicherweise besser, einen LEFT JOIN auf ROW_NUMBER zu verwenden.

;WITH Ord
     AS (SELECT OrderId,
                OrderDate,
                OrderAmount,
                CustomerId,
                ROW_NUMBER() OVER ( PARTITION BY CustomerId 
                                       ORDER BY OrderDate)  AS RN
         FROM   [Order])
SELECT o.OrderId,
       o.OrderDate,
       o.OrderAmount,
       po.OrderAmount
FROM   Ord o
       LEFT JOIN Ord po
         ON o.CustomerId = po.CustomerId
            AND o.RN = po.RN + 1

0voto

Maess Punkte 4090

Ihr WHERE-Klausel ist ungültig, weil das Unterselect keinen Kontext für das o-Alias hat.

Meinten Sie:

ON so.OrderId <> o.OrderId

0voto

MRM Punkte 435
SELECT o.OrderId, o.OrderDate, o.OrderAmount, po.OrderAmount
VON Bestellung o
LEFT JOIN (
   SELECT TOP(1) so.OrderAmount
   VON Bestellung so
   ORDER BY so.OrderDate DESC
   ) po on po.OrderId <> o.OrderId

0voto

syneptody Punkte 1250

Das ROW_NUMBER-Konzept zu verdeutlichen

mit TheOrders als
( 
    select  row_number() over(order by orderdate desc) as RowNum,
            o.OrderId as OrderId
    from Orders o
)
select * from TheOrders

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X