【问题标题】:Show all customers who havent placed an order in a specific time frame显示在特定时间范围内未下订单的所有客户
【发布时间】:2020-06-29 09:06:18
【问题描述】:

对 SQL 和数据库相当陌生...。我有以下问题... 一家航运公司的数据库,这个问题的三个相关表是;

客户(客户 ID、姓名、地址等)

货件(ShipmentID、ScheduleName、DepartDate、ArriveDate、DepartPort、ArrivePort)

CustomerOrder(CustomerID、ShipmentID、Fee 等)

我需要展示 “所有未在特定年份下订单的客户,即 2019 年”我正在努力寻找正确的查询。我正在处理样本数据,数据库中有 8 个客户,其中 3 个有 2019 年出发的货物订单。因此,我希望得到的结果是剩余 5 个没有这些货物订单的客户的列表。

我可以轻松地显示已下订单和从未下过订单的客户,但我很难显示在特定时间范围内未下订单的客户。

任何想法或提示将不胜感激!

谢谢

编辑***

Desired Result - 显示发货日期为 2019 年的 5 位未下订单的客户

我试过了;

~ 从客户中选择客户 ID 左外连接客户订单 ON Customer.CustomerID = CustomerOrder.CustomerID 左外连接装运 ON CustomerOrder.ShipmentID = Shipment.ShipmentID WHERE shipping.DepartDate BETWEEN '2019-01-01' AND '2019-12-31' 并且 CustomerOrder.CustomerID 为空 ~

但是,这不会带来任何结果。

三个表有如下信息

客户 -(客户详细信息的简单表格)(客户 ID、姓名、地址、电话、类型、大小、注册时间)

Shipment -(详细说明每个计划的货件)(ShipmentID、ScheduleName、DepartDate、DepartPort、ArriveDate、ArrivePort、Season)

CustomerOrder -(详细客户订单,但不是订单上的单个商品)(OrderID、ShipmentID、CustomerID)

我不确定它的加入是否是问题所在?样本数据中有 2019 年出货 4 次,客户总数为 3 人。我需要显示在这些日期内未下订单的 5 位客户的 customerID。

我尝试了一些不同的查询,一直在网上搜索,但我是新手,不太确定我哪里出错了。我能够识别从未下过订单的客户,但我一添加日期范围就没有任何结果。

【问题讨论】:

  • 编辑问题添加一些示例数据和所需的结果会有所帮助。
  • 您尝试过什么,或者您进行了哪些研究但还没有理解?关于如何做这样的逻辑有很多。 LEFT JOIN 是最常见的方式。
  • 感谢已编辑问题以尝试更好地解释

标签: sql sql-server select where-clause


【解决方案1】:

我现在不知道您将订单日期保存在哪里,但如果需要,您可以更改任何内容。我使用 DepartDate 来管理与 2019 年不同的订单年份: 示例:

SELECT c.* 
FROM Customer c
INNER JOIN CustomerOrder co ON c.CutomerID = co.CutomerID
INNER JOIN Shipment sh ON co.shipmentID = sh.ShipmentID
WHERE YEAR(sh.DepartDate) <> 2019

获取 DepartDate 不等于 2019

的所有 cutomers 数据

【讨论】:

  • 谢谢,那太好了,但不幸的是,它希望所有在该时间段内未下订单的客户。一些在时间范围内下订单的客户也将其他客户放在了时间范围之外。我只需要展示那些当时没有专门下订单的人。例如。 1 号客户在 2018 年、2019 年和 2020 年下订单。而客户 2 仅在 2018 年下订单。结果只需要显示客户 2(谁在 2019 年没有下订单),但上面的查询还显示客户 1(谁下订单)
  • 从我所做的这个查询中,您应该进行另一个子查询,您可以在其中选择所有已在 2019 年完成订单并排除主题的客户 ID,... 我已经发布了另一个完整查询的帖子。希望有帮助
【解决方案2】:

我认为这可能是您想要的解决方案,这里是完整查询。 子查询意味着您获得了所有在 2019 年下订单的 customerID-s,我们排除了不在...中的主题。

SELECT c.* 
FROM Customer c
INNER JOIN CustomerOrder co ON c.CutomerID = co.CutomerID
INNER JOIN Shipment sh ON co.shipmentID = sh.ShipmentID
WHERE YEAR(sh.DepartDate) <> 2019 AND  c.CutomerID 
  NOT IN (SELECT c.* 
          FROM Customer c
          INNER JOIN CustomerOrder co ON c.CutomerID = co.CutomerID
          INNER JOIN Shipment sh ON co.shipmentID = sh.ShipmentID
          WHERE YEAR(sh.DepartDate) = 2019)

【讨论】:

  • 我相信你已经破解了它!我不得不将子查询中的选择更改为一列,它不允许选择 * 但是它肯定给了我正确的结果!非常感谢,现在就去阅读它并完全理解它!再次感谢
  • @LauraRoscoe 。 . .我认为这不能正确回答您的问题。首先,它要求客户已经下订单——这不是您对问题的描述所要求的。其次,它可以为其他年份多次购买的客户返回重复的行。而且,它比必要的复杂。
  • @gordon-linoff 我认为你错了 - 这是要求:“客户 1 号在 2018 年、2019 年和 2020 年下订单。而客户 2 仅在 2018 年下订单。结果需要仅显示 Laura 要求的客户 2(2019 年未下订单)”
  • Oki doke,所以我对此进行了测试并添加了一个根本没有订单的客户。我运行了查询,它没有显示新客户,所以我认为 gordon 是正确的,因为我需要显示所有在 2019 年没有下过订单的客户(这将包括任何从未下过订单的客户)
  • 是的 - 那是因为 INNER JOIN - 可能有 LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 等,你应该考虑一下 :),INNER JOIN 表示两个表在常见的
【解决方案3】:

Desired Result - 显示发货日期为 2019 年的 5 位未下订单的客户

使用NOT EXISTS:

SELECT c.* 
FROM Customer c
WHERE NOT EXISTS (SELECT 1
                  FROM CustomerOrder co JOIN 
                       Shipment sh
                       ON co.shipmentID = sh.ShipmentID
                  WHERE c.CustomerID = co.CustomerID AND
                       sh.DepartDate >= '2019-01-01' AND
                       sh.DepartDate < '2020-01-01'
                 );

【讨论】:

  • 感谢 Gordon,这似乎成功了。为了更好地理解这一点,您能否解释一下“SELECT 1”的作用?
  • @LauraRoscoe 。 . . exists 子查询只检查 rows 的存在,而不是特定的 values1 是最简单的类型。你可以使用任何东西。我建议不要使用NULL,因为我认为这令人困惑(NULL 不应该意味着存在有效值)。具有讽刺意味的是,在某些数据库中,该表达式甚至会产生错误,例如 1 / 0——但也不要使用它,除非向某人炫耀。
【解决方案4】:

只需在 customerID 不存在的适当日期范围内按 customerId 对订单进行左外连接:

select c.* 
from customers c
    left outer join (
        select customerID 
        from CustomerOrder o 
            join Shipment s on s.ShipmentID=o.ShipmentID 
        where DepartDate>='2020-01-01' and DepartDate<'2021-01-01'
    ) x on x.customerID=c.customerID  
where x.customerid is null

子查询选择在日期范围内订购的每个客户 ID。 左外连接和“customerid is null”对我们的子查询中不存在的客户进行否定匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 2018-10-19
    相关资源
    最近更新 更多