SQL-запрос для извлечения строки с максимальной датой ниже определенной даты - PullRequest
3 голосов
/ 22 июля 2011

Извините, я не мог объяснить это лучше в названии.Вот, по сути, то, что мне нужно сделать:

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 123 для 1/31, так как это самая последняя скамья для entity_id = 1и bench_id 125 для 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

Спасибо, извините, если это простой вопрос, но я работал над ним в течение 6 часов, пробуя всевозможныеподзапросы, агрегаты, GROUP BY и все такое.Я не настолько опытен с SQL.

:)

Ответы [ 2 ]

3 голосов
/ 22 июля 2011

Это НЕ простая проблема, она тоже заняла у меня много времени.По сути, тот же вопрос, что и Mysql - необходимо получить самую последнюю из таблицы A, если на нее ссылаются из таблицы 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 голос
/ 22 июля 2011

Таким образом, вы хотите только 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, работайте на вашем уровне принятия ....

РЕДАКТИРОВАТЬ: С другой стороны, если вы хотите полностью исключить скамейки, если у них были даты, превышающие дату_эффективного, вы можете использовать предложение HAVING, пожалуйста, сообщите, если это так ... .

РЕДАКТИРОВАТЬ: отредактированный запрос, чтобы отразить ваши вопросы редактирования.

...