用于条件连接的SQL查询

时间:2011-02-28 03:47:02

标签: sql

我有这两个表:

Customers: Id, Name
Orders: Id, CustomerId, Time, Status

我想获得最终订单的状态为“错误”的客户列表。

我知道如何使用LEFT JOIN来获取每个客户的订单数量,但我不知道如何将此声明用于我想要的内容。也许JOIN也不适合使用,我不确定。

客户可能没有订单,应该退货。

我在这里抽象真实的表格,但场景是针对Windows手机应用程序发送通知。我想让所有客户的最后通知没有“丢弃”状态。我可以通过“时间”字段对通知(订单)进行排序。感谢您的帮助,同时我继续在where子句中尝试子查询。

4 个答案:

答案 0 :(得分:1)

假设最后一个订单引用时间列,这里是我的查询:

SELECT C.Id,
       C.Name,
       MAX(O.Time)
FROM
     Customers C

  INNER JOIN Orders O 
  ON C.Id = O.CustomerId

WHERE
     O.Status != 'Wrong'

GROUP BY C.Id,
         C.Name

修改

关于您的表配置。您应该考虑修改结构以包含第三个表。它们看起来像这样:

Customer 
  CustomerId | Name 

Order

  OrderId  | Status | Time

CompletedOrders

  CoId  | CustomerId | OrderId

现在您要做的是将有关客户或订单的信息存储在各自的表中......然后在下订单时,您只需创建一个带有2条单独记录的ID的CompletedOrders条目。这将允许客户和订单之间的1对多关系。

答案 1 :(得分:1)

Select ...
From Customers As C
Where Not Exists    (
                    Select 1
                    From Orders As O1
                        Join    (
                                Select O2.CustomerId, Max( O2.Time ) As Time 
                                From Orders As O2
                                Group By O2.CustomerId
                                ) As LastOrderTime
                            On LastOrderTime.CustomerId = O1.CustomerId
                                And LastOrderTime.Time = O1.Time
                    Where O1.Status = 'Dropped'
                        And O1.CustomerId = C.Id
                    )

显然有基于实际数据库产品和版本的替代方案。例如,在SQL Server中,可以使用TOP命令或CTE。但是,在不知道正在使用哪种特定产品的情况下,上述解决方案应该能够在几乎任何数据库产品中产生您想要的结果。

<强>加成

如果您使用的产品支持排名功能(未提及哪个数据库产品和版本)和公用表表达式,那么替代解决方案可能是这样的:

With RankedOrders As
    (
    Select O.CustomerId, O.Status
        , Row_Number() Over( Partition By CustomerId Order By Time Desc ) As Rnk
    From Orders As O
    )
Select ...
From Customers
Where Not Exists    (
                    Select 1
                    From RankedOrders As O1
                    Where O1.CustomerId = C.Id
                        And O1.Rnk = 1
                        And O1.Status = 'Dropped'
                    )

答案 2 :(得分:0)

没有检查出来,但这样的事情呢?

SELECT c.CustmerId,c.Name,MAX(o.Time) 来自客户c LEFT JOIN Orders o ON o.CustomerId = c.CustomerId 在哪里o.Status&lt;&gt; '错误' GROUP BY c.CustomerId,C.Name

答案 3 :(得分:0)

您可以获取具有“错误”状态的最终订单的客户列表

从status ='Wrong'的订单中选择customerId  按customerId分组 有时间=最大(时间)