Соединения неэквивалентности - PullRequest
5 голосов
/ 24 марта 2011

Я занимался SQL в течение нескольких лет, и все это время я думал о объединениях как об эквивалентных объединениях, как в

select ... from t1 join t2 on t1.a = t2.b

Обратите внимание, как объединение основано на одном или несколькихравенства здесь t1.a = t2.b.Однако в последнее время я не помню, где, я видел соединение неэквивалентности (я только что придумал этот термин, скажите, пожалуйста, есть ли для него реальное имя), где условие соединения содержит хотя бы одно неравенство,как в

select ... from t1 join t2 on t1.a > t2.b

Что можно сделать, чтобы сделать некоторые хорошие вещи, особенно с внешними объединениями.Позвольте мне проиллюстрировать это на примере.

Давайте рассмотрим таблицу с названием products, со следующими данными:

product   year  price
----------------------
apple   2009    4
apple   2008    2
apple   2007    5
apple   2006    6
apple   2005    2
banana  2009    9
banana  2008    12
banana  2007    16
banana  2006    15
banana  2005    10

И мы хотим сделать обычный «дай мне самый дорогой год для«каждый продукт», который, насколько я знаю, обычно выполняется с помощью внутреннего соединения с той же таблицей, сгруппированной по продуктам, например:

select t1.`name`, t1.`year`, t1.`price`
from products as t1 join
( select `name`, max(`price`) as `max_price` from products group by `name` ) as t2 on t1.`name`=t2.`name` and t1.`price`=t2.`max_price`

Итак, на t2 мы получаем максимумцена для каждого продукта, а затем мы объединяем этот результат с той же таблицей, чтобы получить оставшиеся данные для этого столбца (это становится немного сложнее для разрыва связей)

Однако, с внешним объединением с неэквивалентностью, мы можем сделать это так:

select t1.`name`, t1.`year`, t1.`price`
from products as t1 left join products as t2 on t1.`name`=t2.`name` and t1.`price` < t2.`price`
where t2.`name` is null

На этот раз мы дважды присоединяемся к одной таблице, где цена на t1 меньше, чем цена на t2.Хитрость заключается в том, что, поскольку это левое внешнее соединение, значения t2 в результирующем соединении будут нулевыми, если соединение не совпадает, что происходит для максимального значения цены.

Оба эти запросадать тот же результат, но я не совсем уверен, какой из них работает лучше.Первый запрос имеет дорогую группировку, а второй должен вручную проверить все пары t1 / t2, чтобы получить результат.Разрыв связи, кажется, легче с объединением неэквивалентности.

Итак, мой вопрос:

Существуют ли какие-либо рекомендуемые источники (книги, веб-страницы), которые более подробно обсуждают объединения неэквивалентности?, объясняя, что вы можете сделать с ними (я предполагаю, что вы можете сделать гораздо больше, чем просто получать максимальные значения в группах), и как они работают с другими методами для выполнения тех же самых действий?

Редактировать: Я знаюФункции управления окнами также доступны для выполнения таких вещей, как тривиальный пример, который я упоминал выше.Я не спрашиваю, как получить максимальное значение таблицы.Я знаю, как это сделать, и я даже предоставил два способа сделать это.Я хочу знать, что еще я могу сделать с соединениями неэквивалентности.

Ответы [ 2 ]

2 голосов
/ 24 марта 2011

И мы хотим сделать обычный «дай мне самый дорогой год для каждого продукта», который, насколько я знаю, обычно делается с внутренним соединением к той же таблице, сгруппированной по продуктам, например, так

Гораздо проще сделать с помощью оконной функции (как уже упоминал jonealres)

select name, 
       year, 
       price,
       max(price) over (partition by name) as most_expensive
from products
0 голосов
/ 24 марта 2011

Я делал подобные вещи здесь SQL-запрос Создание начальной и конечной даты и здесь Логическая группировка SQL Server за последнее время .

Этот тип объединений не отличаетсязатем «равенство».Предложение on - это просто логическая оценка.Если индексы существуют, то они оцениваются близко к предложению where по индексам.

Кроме того, это зависит от воображения каждого.SQL богат, поэтому его можно комбинировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...