【问题标题】:Mysql Select events from last year but not this yearMysql 选择去年但今年没有的事件
【发布时间】:2013-07-09 00:13:41
【问题描述】:

我需要一些关于查询的指示。

我有一个订单表。它具有以下列(除其他外)

OrderID | OrderDate | CustomerID

我想找到2012年订购但2013年没有订购的客户。

(实际上我最终会想要更高的精度(2012 年 3 月订购的客户,但不是 2013 年))

我知道我可以做两个查询 -

"SELECT * FROM TABLE WHERE OrderDate BETWEEN 2012-01-01 AND 2012-12-31"
"SELECT * FROM TABLE WHERE OrderDate BETWEEN 2013-01-01 AND 2013-12-31"

然后再分析结果,不过好像用纯mysql应该是可以的。

也许是自我加入?还是嵌套的 SELECT?我对这些不是很熟悉,很难找到相关的例子。感谢您的帮助!

【问题讨论】:

    标签: php mysql inner-join self-join


    【解决方案1】:

    不需要连接;仅在按客户分组时过滤订单:

    SELECT   CustomerID
    FROM     Orders
    GROUP BY CustomerID
    HAVING   SUM(OrderDate BETWEEN 2012-03-01 AND 2012-03-31)
     AND NOT SUM(OrderDate BETWEEN 2013-01-01 AND 2013-12-31)
    

    【讨论】:

    • 如果表很大,这可能是一个非常慢的查询,因为它无法被索引。
    【解决方案2】:

    eggyal 的答案会起作用,但它可能会很慢,因为它不能利用索引。假设您在OrderDate 上有一个索引,则以下自联接可能会更好:

    SELECT DISTINCT o1.CustomerID
    FROM Orders o1
    LEFT JOIN Orders o2
    ON o1.CustomerID = o2.CustomerID
    AND o2.OrderDate BETWEEN '2013-01-01' AND '2013-12-31 23:59:59'
    WHERE o1.Orderdate BETWEEN '2012-01-01' AND '2012-12-31 23:59:59'
    AND o2.CustomerID IS NULL
    

    【讨论】:

    • 嗯,我真的很喜欢 eggyal 的简单回答,但我不得不选择这个,因为它快了 3 倍,并且最终将更适合不同的用途。谢谢
    【解决方案3】:

    我的查询更具可读性。只是从 2012 年的客户中减去 2013 年的客户。

    SELECT `CustomerID` 
    FROM `d` 
    WHERE 
       `OrderDate` BETWEEN '2012-01-01' AND '2012-12-31 23:59:59' 
       AND `CustomerID` NOT IN
           (SELECT `CustomerID` 
            FROM `d` 
            WHERE 
                `OrderDate` BETWEEN '2013-01-01' AND '2013-12-31 23:59:59' 
            GROUP BY `CustomerID`)
       GROUP BY `CustomerID`
    

    还有一些关于如何rewrite query with subquery to query with join 的信息(@Barmar 的解决方案)。

    【讨论】:

      猜你喜欢
      • 2019-09-18
      • 2020-08-28
      • 2017-09-19
      • 2018-04-25
      • 2021-02-16
      • 2016-11-08
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      相关资源
      最近更新 更多