【问题标题】:Limit LEFT JOIN to a maximum of one results将 LEFT JOIN 限制为最多一个结果
【发布时间】:2019-11-15 09:01:08
【问题描述】:

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

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

为了跟踪订单是否已打包,我想加入另一个名为“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 中的重复项,以免它们弄乱总数?

【问题讨论】:

  • '我怎样才能摆脱 JOIN 中的重复项,这样它们就不会弄乱总数' - 将左连接更改为选择不同 orders_sent_id 的子查询上的左连接
  • '"finished" 但不在已发送的表中,应该完全忽略,' - 真的 - 这是否意味着它不应该被视为已放置?
  • 没错。例如,已取消或更改的订单被标记为已完成。例如,更改的订单会获得新的 order_id。这是一个糟糕的系统。 :)
  • 为了澄清,我只想计算应该已发送的订单。这个目的是计算我们能够在放置后 24 小时内发送多少。我还有其他一些取消资格,例如不计算缺货订单以及本示例不需要的。您的第一条评论也解决了我的问题。因此,我将其发布为答案。谢谢!

标签: mysql asp-classic


【解决方案1】:

根据@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。

【讨论】:

    猜你喜欢
    • 2015-01-19
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多