简体   繁体   中英

Selecting the most recent result from one table joining to another

I have two tables.

One table contains customer data, like name and email address. The other table contains a log of the status changes.

The status log table looks like this:

+-------------+------------+------------+
| 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 |     
+-------------+------------+------------+

And the customer data:

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

I would like to select the customer's who have "Bought" in July (07). But exclude customers who's status has changed from "Bought" anything other most recently.

The result should be just one customer (Philip) - all the others have had their status change to something other than Bought most recently.

I have the following 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

But that is as far as I have got! The above query only returns one result, but essentially there could be more than one.

Any help is appreciated!

Here is an approach that uses a correlated subquery to get the most recent status record:

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;

Notes:

  • Use meaningful table aliases! That is, abbreviations for the table names, rather than arbitrary letters such as a and b .
  • Use proper date arithmetic. LIKE is for strings. MySQL has lots of date functions that work.
  • In MySQL 8+, you would use ROW_NUMBER() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM