繁体   English   中英

用于条件连接的SQL查询

[英]SQL query for join with condition

我有这两个表:

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

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

我知道如何使用LEFT JOIN来获取每个客户的订单数量,但我不知道如何将此语句用于我想要的内容。 也许JOIN不是正确使用的东西,我不确定。

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

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

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

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对多关系。

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'
                    )

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

SELECT c.CustmerId,c.Name,MAX(o.Time)FROM Customers c LEFT JOIN Orders o ON o.CustomerId = c.CustomerId WHERE o.Status <>'Wrong'GROUP BY c.CustomerId,C.Name

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

从订单中选择customerId,其中status ='Wrong'group by customerId,time = max(time)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM