[英]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.