TSQL在子查询中无效where子句

时间:2011-12-14 19:09:11

标签: sql sql-server tsql

我有一种情况需要使用select语句在一行中选择当前和之前的订单金额。

订单表:

Customer Id
OrderId
OrderDate
OrderAmount

当前选择声明:

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

问题是不允许子查询中的“where”子句。是否有其他方法可以获取此信息。

这实际上是对更复杂的选择(对于视图)的简化,需要当前和上一个报告期的财务报告数据。

4 个答案:

答案 0 :(得分:8)

这里需要OUTER APPLY

您的WHERE子句看起来不正确。我认为OrderDate在确定“上一行”时是唯一的。

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  

但是你可能会更好地离开加入ROW_NUMBER

;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  

答案 1 :(得分:0)

在此处输入代码您的WHERE子句无效,因为子选择没有o别名的上下文。

你的意思是:

ON so.OrderId <> o.OrderId

答案 2 :(得分:0)

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

答案 3 :(得分:0)

说明ROW_NUMBER的想法

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