SQL-查询以获取具有低于特定日期的最大日期的行

时间:2011-07-22 17:43:14

标签: sql greatest-n-per-group

抱歉,我无法在标题中更好地解释这一点。这基本上是我需要完成的事情:

Entity table: entity_id

BenchHistory table: entity_id, bench_id, bench_effective_date

Summary table: entity_id, effective_date

简而言之,这就是数据库布局。此查询从effective_date表中查找每个实体的Summary。它还需要找到该特定日期的bench_id,方法是查看BenchHistory表并查找小于bench_effective_date effective_date的最大BenchHistory.entity_id = Entity.entity_id 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

这就是我所拥有的:

BenchHistory.bench_id

非常简单,替补部分是我遇到的麻烦。如何只选择一个Summary.effective_date,它必须是effective_dates的最新相对位置?

为清楚起见,每个实体都有许多对应的bench_ids和许多对应的bench_id,但一次只有一个bench_id可以“有效”(最近的一个)。我试图找到每一行的“有效”effective_date,具体取决于该行的bench_id。我需要通过确定哪个bench_effective_date effective_date小于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 Entity.entity_id = BenchHistory.entity_id 来实现此目的。

以下是我所拥有的查询示例,可能会更容易进行可视化。

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

这将输出如下:

bench_id

我想要抓取的是1/31的entity_id = 1 123,因为它是bench_id的最新工作台,而12月30日是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 125等等。所以结果集:

{{1}}

谢谢,对不起,如果这是一个简单的问题,但我一直在努力工作6个小时,尝试各种子查询,聚合,GROUP BY等等。我不熟悉SQL。

:)

2 个答案:

答案 0 :(得分:3)

这不是一个简单的问题,它花了我很多时间。基本上与Mysql - Need to get latest of table A when referenced from table B相同的问题与mysql功能请求http://bugs.mysql.com/bug.php?id=2020有关,请参阅信息。

对你来说最简单的方法就是遵循这个例子:

假设您有每个商店中每件商品的价格表。对于每件商品,您希望看到最低价格和相关商店,您可以在价格中获得它!与您的示例完全相同 - 您需要具有最大修订版本的记录。

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;

答案 1 :(得分:1)

所以你只想JOIN你的最大日期小于摘要的工作台

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,按你的录取率工作......

编辑:另一方面,如果你想要完全排除长凳,如果他们的日期大于effective_date你可能会使用HAVING条款,请告知是否是这种情况....

编辑已修改的查询以反映您的问题修改。