首页 > 解决方案 > 将 LEFT JOIN 限制为最多一个结果

问题描述

我正在尝试计算两次之间我们收到的订单数量,以及仓库工作人员打包的订单数量。

我们有一个包含订单的“订单”表,当订单完成时,不幸的是,当订单以不应添加到计算中的取消订单等方式处理时,它将收到“已完成”状态,即太多我无法更改的遗留代码。

为了跟踪订单是否已打包,我想加入另一个名为“orders_sent”的表,但不幸的是,如果一个订单有多个包裹,那么该表中的该 orders_id 将有不止一行。

所以我想做的是检查订单是否已经下达,如果它已经“完成”并且也存在于已发送表中,我会将其视为已发送,如果它“已完成”但不在已发送表中,它应该被完全忽略,最后我想计算所有行的总数,忽略任何重复,因为发送表中有多个条目。

到目前为止,这是我想出的。

"SELECT " &_
"   COUNT(CASE orders_status WHEN 'Finished' THEN 1 ELSE NULL END) AS Sent, " &_
"   COUNT(*) AS Total " &_
"FROM " &_
"   orders " &_
"   LEFT JOIN orders_sent ON orders_id = orders_sent_orderid " &_
"WHERE " &_
"   orders_date > '" & datetime & "' " &_
"   AND orders_date < '" & dateAdd("d",1,datetime) & "' " &_
"   AND NOT (" &_
"       orders_status = 'FINISHED' " &_
"       AND orders_sent_id IS NULL) "

我尝试对orders_sent_id 进行分组,但这不起作用,因为已发送表中不存在的所有订单都被分组在一起。尝试按 orders_id 分组给了我无法解释的奇怪结果(已发送 6 个,总共 6 个)。不分组给了我 33 个发送,总共 54 个。

运行 SQL,跳过计数并仅显示 orders_ID,我使用下面的 SQL 在该时间段内总共获得 47 个订单。不分组显示一些重复的 ID,因为 orders_sent 包含几个订单的多行。

"SELECT " &_
"   orders_id AS oid " &_
"FROM " &_
"   orders " &_
"   LEFT JOIN orders_sent ON orders_id = orders_sent_orderid " &_
"WHERE " &_
"   orders_date > '" & datetime & "' " &_
"   AND orders_date < '" & dateAdd("d",1,datetime) & "' " &_
"   AND NOT (" &_
"       orders_status = 'Skickad och avslutad' " &_
"       AND orders_sent_id IS NULL) " &_
"GROUP BY " &_
"   orders_id"

那么我怎样才能摆脱 JOIN 中的重复项,以免它们弄乱总数呢?

标签: mysqlasp-classic

解决方案


根据@P.Salmon 的评论,这是修正后的 SQL,似乎已经解决了我的问题:

"SELECT " &_
"   COUNT(CASE WHEN orders_status = 'Finished' AND os.orders_sent_ts < '" & dateAdd("h",27,datetime) & "' THEN 1 ELSE NULL END) AS Sent, " &_
"   COUNT(*) AS Total " &_
"FROM " &_
"   orders " &_
"   LEFT JOIN (" &_
"       SELECT DISTINCT " &_
"           orders_sent_orderid, " &_
"           orders_sent_ts " &_
"       FROM " &_
"           orders_sent "&_
"       WHERE " &_
"           1) AS os ON orders_id = os.orders_sent_orderid " &_
"WHERE " &_
"   orders_date > '" & datetime & "' " &_
"   AND orders_date < '" & dateAdd("d",1,datetime) & "' " &_
"   AND NOT (" &_
"       orders_status = 'Finished' " &_
"       AND os.orders_sent_orderid IS NULL) "

我从我的 CASE 中的 orders_sent 表中添加了一个时间戳,以确保我可以返回任何日期并查看当天的工作情况。+27 小时是因为卡车在 15:00 出发,但应该在同一天发送的订单的截止时间是 12:00。


推荐阅读