开发者

SQL- Query to fetch the row having a maximum date below a certain date

Sorry I couldn't explain this better in the title. Here is essentially what I need to accomplish:

Entity table: entity_id

BenchHistory table: entity_id, bench_id, bench_effective_date

Summary table: entity_id, effective_date

That is the database layout in a nutshell. This query finds each entity's effective_date from the Summary table. It also needs to find the bench_id for that particular date, by looking through the BenchHistory table and finding the maximum bench_effective_date that is less than effective_date where BenchHistory.entity_id = Entity.entity_id.

Here is what I have:

SELECT
    Entity.entity_id
    Summary.effective_date
    BenchHistory.bench_id
FROM
    Entity
JOIN Summary ON Entity.entity_id = Summary.entity_id
JOIN BenchHistory ON Entity.entity_id = BenchHistory.entity_id

Pretty simple, the bench part is what I'm having trouble with. How do I select only one BenchHistory.bench_id, that must be the most recent relative to Summary.effective_date?

For clarity, Each entity has many corresponding effective_dates and many corresponding bench_ids, but only one bench_id can be "valid" at a time (the most recent one). I am trying to find each row's "valid" bench_id depending on that row's effective_date. I need to do this by determining which bench_id has a bench_effective_date less than effective_date.

Here is an example of a query that I have, maybe it will be easier to visualize then.

SELECT
    Entity.entity_id
    BenchHistory.bench_id
    Summary.effective_date
    BenchHistory.bench_effective_date
FROM
    Entity
JOIN Summary ON Entity.entity_id = Summary.entity_id
JOIN BenchHistory ON En开发者_运维百科tity.entity_id = BenchHistory.entity_id

This will give output like:

entity_id    bench_id    effective_date    bench_effective_date
1            120         1/31/2011         6/30/2003
1            121         1/31/2011         3/22/2005
1            122         1/31/2011         11/03/2008
1            123         1/31/2011         1/21/2011
1            124         12/30/2010        5/15/2010
1            125         12/30/2010        10/06/2010

What I want to grab, is just bench_id 123 for 1/31, as it is the most recent bench for entity_id = 1 and bench_id 125 for 12/30, etc. So a result set:

entity_id    bench_id    effective_date    bench_effective_date
1            123         1/31/2011         1/21/2011
1            125         12/30/2010        10/06/2010

Thank you, sorry if this is an easy question but I have been working on it for 6 hours trying all sorts of subqueries, aggregates, GROUP BY, and whatever. I am not that experienced with SQL.

:)


This is NOT an easy problem, it took me a lot time too. Basically the same question as Mysql - Need to get latest of table A when referenced from table B and is related to mysql feature request http://bugs.mysql.com/bug.php?id=2020 , see it for info.

Maybe easiest for you is to follow this example:

Suppose you have table with price for each goods in each store. For each goods, you want to see the minimal price and the related store, in which you get it for the price! Exactly the same as in your example - you want a record with max revision.

create table prices ( goods varchar(10), price double, store varchar(10) );

insert into prices values ('car', 200, 'Amazon'), ('car', 150, 'CarStore'), ('Bread', 2, 'Baker1'), ('Bread', 1, 'Baker2');

select goods, min(price), 
    (select store 
     from prices as p 
     where p.goods = prices.goods
     order by price limit 1) as store
from prices
group by goods;


So you want to only JOIN the bench table where you have the max date less than the summary

SELECT
    Entity.entity_id
    ,BenchHistory.bench_id
    ,Summary.effective_date
    ,BenchHistory.bench_effective_date
FROM
    Entity
JOIN Summary 
    ON Summary.entity_id = Entity.entity_id
JOIN BenchHistory 
    ON BenchHistory.bench_id IN
        (
        SELECT TOP 1
            z.bench_id
        FROM
            BenchHistory z
        WHERE 
            z.entity_id = Summary.entity_id
            AND z.bench_effective_date <= Summary.effective_date
        ORDER BY
            z.bench_effective_date DESC
        )

PS, work on your acceptance rate....

EDIT: On the other hand if you wanted to exclude benches entirely if they had any dates greater than the effective_date you might use a HAVING clause, please advise if this is the case....

EDIT: edited query to reflect your question edits.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜