简体   繁体   中英

How to get latest value of field within a join in mysql

Consider two tables:

house_market_changes
 date        | house_id | market_status
---------------------------------
 2013-04-03  | 1        | "on"
 2013-04-06  | 1        | "under offer"
 2013-04-11  | 1        | "off"
 2013-04-02  | 2        | "on"
 ...

house_market_changes tells us what the house changed to and when.

agent_visit
 date        | house_id | agent_id
---------------------------------
 2013-04-05  | 1        | 1
 2013-04-06  | 1        | 1
 2013-04-08  | 1        | 1
 2013-04-09  | 1        | 1
 2013-04-10  | 1        | 1
 2013-04-12  | 1        | 1
 ...

agent_visit tells us when an agent went to visit a house.

I want a query with these results:

agent_visit_info
 date        | house_id | agent_id | house_market_status
-----------------------------------------------
 2013-04-05  | 1        | 1        | "on"
 2013-04-06  | 1        | 1        | "under offer"
 2013-04-08  | 1        | 1        | "under offer"
 2013-04-09  | 1        | 1        | "under offer"
 2013-04-10  | 1        | 1        | "under offer"
 2013-04-12  | 1        | 1        | "off"
 ...

The house_market_status column tells us what the status of the house was on that date. So house_market_status is the latest value of market_status before or on the date of the visit.

Anyone know how to do this?

This is a messy statement but I think will give you your desired result,

SELECT  b.*, a.market_status
FROM
        (
            SELECT  a.date StartDate,
                    COALESCE(b.date - INTERVAL 1 DAY, a.date + INTERVAL 999 YEAR) EndDate,
                    a.house_id,
                    a.market_status
            FROM
                    (
                        SELECT  a.date, 
                                a.house_id, 
                                a.market_status,
                                (
                                    SELECT  COUNT(*)
                                    FROM    house_market_changes b
                                    WHERE   b.house_id = a.house_id AND
                                            b.date <= a.date
                                ) AS RowNumber
                        FROM    house_market_changes a
                    ) a 
                    LEFT JOIN
                    (
                        SELECT  a.date, 
                                a.house_id, 
                                a.market_status,
                                (
                                    SELECT  COUNT(*)
                                    FROM    house_market_changes b
                                    WHERE   b.house_id = a.house_id AND
                                            b.date <= a.date
                                ) AS RowNumber
                        FROM    house_market_changes a
                    ) b ON  a.house_id = b.house_id AND
                            a.RowNumber + 1 = b.RowNumber
        ) a
        INNER JOIN agent_visit b
            ON  b.date BETWEEN a.StartDate AND a.EndDate AND
                a.house_id = b.house_id

OUTPUT

╔════════════╦══════════╦══════════╦═══════════════╗
║    DATE    ║ HOUSE_ID ║ AGENT_ID ║ MARKET_STATUS ║
╠════════════╬══════════╬══════════╬═══════════════╣
║ 2013-04-05 ║        1 ║        1 ║ on            ║
║ 2013-04-06 ║        1 ║        1 ║ under offer   ║
║ 2013-04-08 ║        1 ║        1 ║ under offer   ║
║ 2013-04-09 ║        1 ║        1 ║ under offer   ║
║ 2013-04-10 ║        1 ║        1 ║ under offer   ║
║ 2013-04-12 ║        1 ║        1 ║ off           ║
╚════════════╩══════════╩══════════╩═══════════════╝

Brief Explanation:

The query needs to generate sequential number for every house_id which will be used to join on the other subquery to get the starting date and the ending date of the market_status . The resulting record of the subquery will be joined on table agent_visit via house_id and that the date falls between the date ranges of the market_status .

The logic of your ploblem is the next one.

You need to compare the first row date field to the second row field from house_market_changes table and check the range between em. If date1 < date2, all the rows from agent_visit table will have date1's market_status and do it again for the next iteration ( if(date2 < date3) ... ).

My problem is I'm not that pro in SQL so I can't traduce it to SQL code, I hope this help you in any form

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