代码之家  ›  专栏  ›  技术社区  ›  beingalex

从一个表连接到另一个表中选择最近的结果

  •  1
  • beingalex  · 技术社区  · 6 年前

    我有两张桌子。

    一个表包含客户数据,如姓名和电子邮件地址。另一个表包含状态更改的日志。

    状态日志表如下所示:

    +-------------+------------+------------+
    | customer_id | status     | date       |
    +-------------+------------+------------+
    | 1           | Bought     | 2018-07-01 |     
    | 1           | Bought     | 2018-07-02 |     
    | 2           | Ongoing    | 2018-07-03 |     
    | 3           | Ongoing    | 2018-07-04 |     
    | 1           | Not Bought | 2018-07-05 |     
    | 4           | Bought     | 2018-07-06 |     
    | 4           | Not Bought | 2018-07-07 |     
    | 4           | Bought     | 2018-07-08 | *    
    | 3           | Cancelled  | 2018-07-09 |     
    +-------------+------------+------------+
    

    以及客户数据:

    +-------------+------------+
    | id | name   | email      |
    +-------------+------------+
    | 1  | Alex   | alex@home  |
    | 2  | John   | john@home  |
    | 3  | Simon  | si@home    |
    | 4  | Philip | phil@home  |
    +-------------+------------+
    

    我想选择7月(07年)已经“购买”的客户。但不包括最近状态从“购买”其他任何东西改变的客户。

    结果应该只有一个客户(philip)-所有其他客户的状态都发生了变化,而不是最近购买的。

    我有以下SQL:

    SELECT 
        a.customer_id
    FROM
        statuslog a
    WHERE
        DATE(a.`date`) LIKE '2018-07-%'
            AND a.status = 'Bought'
            ORDER BY a.date DESC
            LIMIT 1
    

    但那是我所能做到的!上面的查询只返回一个结果,但实际上可能有多个结果。

    感谢您的帮助!

    1 回复  |  直到 6 年前
        1
  •  3
  •   Gordon Linoff    6 年前

    下面是一种使用相关子查询获取最新状态记录的方法:

    SELECT sl.customerid
    FROM wwym_statuslog sl
    WHERE sl.date = (SELECT MAX(sl2.date)
                     FROM wwym_statuslog sl2
                     WHERE sl2.customer_id = sl.customer_id AND
                           sl2.date >= '2018-07-01' AND
                           sl2.date < '2018-08-01'
                    ) AND
          sl.status = 'Bought'
    ORDER BY sl.date DESC
    LIMIT 1;
    

    笔记:

    • 使用有意义的表别名!也就是说,表名的缩写,而不是任意的字母,比如 a b 是的。
    • 使用正确的日期算法。 LIKE 是为了弦。mysql有很多可以工作的日期函数。
    • 在mysql 8+中,您可以使用 ROW_NUMBER() 是的。