У меня есть следующие структуры таблицы:SQL присоединиться к коррелированных подзапросов, где таблицы связаны с помощью перекрывающихся диапазонов
Пункт
ID | Name
--------
1 | Apple
2 | Pear
3 | Banana
4 | Plum
5 | Tomato
событий
ItemStart | ItemEnd | EventType | EventDate
--------------------------------------------
1 | 2 | Planted | 2014-01-01
1 | 3 | Picked | 2014-01-02
3 | 5 | Eaten | 2014-01-05
две таблицы связанный только с первичным ключом Item и диапазоном ItemStart и ItemEnd (включительно) в событии. События всегда относятся к смежным последовательностям элементов, но не все события для данного элемента будут иметь одинаковый диапазон. События никогда не появляются в тот же день для данного элемента.
Запрос Я хотел бы производить следующим образом: выход
List all the Items, and for each Item show the most recent Event
Пример:
ID | Name | Event | Date
----------------------------
1 | Apple | Picked | 2014-01-02 (Planted then Picked)
2 | Pear | Picked | 2014-01-02 (Planted then Picked)
3 | Banana | Eaten | 2014-01-05 (Picked then Eaten)
4 | Plum | Eaten | 2014-01-05 (Eaten)
5 | Tomato | Eaten | 2014-01-05 (Eaten)
Это кажется достаточно разумным, на лице его, и если там были традиционными отношения внешнего ключа на месте (представьте ItemID
вместо ItemStart
и ItemEnd
). Я бы, вероятно, присоединился к коррелированному подзапросу примерно так:
SELECT Name, EventType, EventDate
FROM Item i
INNER JOIN (
SELECT ItemID, EventType, EventDate
FROM Event e
WHERE EventDate = (SELECT MAX(EventDate) FROM Event e_max WHERE e_max.ItemID = e.ItemID)
) latest_events ON i.ID = latest_events.ItemID
Однако, с отношением расстояния в месте я застрял, я хочу сделать что-то больше похоже на это, но он не работает:
SELECT Name, EventType, EventDate
FROM Item i
INNER JOIN (
SELECT ItemStart, ItemEnd, EventType, EventDate
FROM Event e
WHERE EventDate = (SELECT MAX(EventDate) FROM Event e_max WHERE i.ID >= e_max.ItemStart AND i.ID <= e_max.ItemEnd)
) latest_events ON i.ID >= latest_events.ItemStart AND i.ID <= latest_events.ItemEnd
Я получаю ошибку о i.ID >= e_max.ItemStart AND i.ID <= e_max.ItemEnd
в строке 6 , потому что вы не можете ссылаться на i
из другой части соединения. Я хотел сделать это (что не обязательно в более простом примере), потому что, когда я создаю подзапрос, у меня больше нет единого идентификатора для ссылки - перекрывающиеся диапазоны означают, что существует много возможных способов включения одного элемента , и поэтому я хочу обратиться непосредственно к этому элементу, чей идентификатор доступен только в таблице позиций верхнего уровня.
Надеюсь, это имеет смысл.
Я использую SQL Server 2008 R2. Это для отчета, который будет работать в одночасье, поэтому скорость не такая важная, как это может быть, но очень много предметов (100 миллионов); в то время как есть несколько событий против каждого элемента, использование больших диапазонов означает, что записей событий намного меньше.
Вещи я думал:
- Каким-то образом расширяется из отношения Пункт/событие, так что события записываются против всех отдельных предметов. Это приведет к значительному увеличению объема рассматриваемых данных, но позволит упростить подход к поиску.
- Как-то обрабатывать события, чтобы ограничить или объединить диапазоны - если бы я знал, что для данного элемента все его События имели одинаковое начало и конец, я мог бы упростить вещи. Не все так хорошо.
Как я могу произвести этот запрос? Заранее спасибо!
Я не уверен, если я понял, так как я не мог следовать вашему ожидается пример вывода. Может быть, вы могли бы присоединиться к нему более traditionaly с помощью представления 'CREATE VIEW V_EVENT в Выберите ItemStart как Item, EventType, EVENTDATE UNION Выберите ItemEnd, EventType, EVENTDATE ' – bummi
возможно дубликат [SQL - Нахождение максимальной группы дат таблицей идентификаторов ] (http://stackoverflow.com/questions/25529320/sql-finding-the-maximum-date-group-by-id-table) – Bulat