JOIN с самим собой

Можно подробнее описать этот запрос нарастающего итога?

SELECT O1.OrderID, O1.Freight, SUM(O2.Freight) FROM Orders O1
INNER JOIN Orders O2 ON O2.OrderID <= O1.OrderId
GROUP BY O1.OrderID, O1.Freight

Я понимаю как работает INNER JOIN. Но почему мы пишем SUM(O2.Freight), а не SUM(O1.Freight) мне не понятно. Если сделать SUM(O1.Freight), то результат другой соответственно. Спасибо!


Ответы (2 шт):

Автор решения: Герман Борисов

Условие O2.OrderID <= O1.OrderId означает, что в O2 будут все, (видимо заказы) номер которых меньше или равен текущему из O1, то есть все предшествующие текущей строке и сама текущая строка.

Это собственно определение нарастающего итога — сумма из всех предшествующих строку плюс текущая.

→ Ссылка
Автор решения: Akina

Объясняющий пример.

  1. Создадим исходные данные.
CREATE TABLE Orders
SELECT 1 OrderID, 1 Freight UNION ALL
SELECT 2,2 UNION ALL
SELECT 3,3;
  1. Ваш запрос
SELECT O1.OrderID, O1.Freight, SUM(O2.Freight) FROM Orders O1
INNER JOIN Orders O2 ON O2.OrderID <= O1.OrderId
GROUP BY O1.OrderID, O1.Freight
ORDER BY O1.OrderID, O1.Freight
OrderID Freight SUM(O2.Freight)
1 1 1
2 2 3
3 3 6
  1. Как работает ваш запрос?

Выведем детально каждую связанную строку.

SELECT O1.OrderID, O1.Freight, 
       O2.OrderID, O2.Freight,
       SUM(O2.Freight) OVER (PARTITION BY O1.OrderID, O1.Freight) AS `SUM(O2.Freight)`
FROM Orders O1
INNER JOIN Orders O2 ON O2.OrderID <= O1.OrderId
ORDER BY O1.OrderID, O1.Freight
OrderID Freight OrderID Freight SUM(O2.Freight)
1 1 1 1 1
2 2 1 1 3
2 2 2 2 3
3 3 1 1 6
3 3 2 2 6
3 3 3 3 6

fiddle

→ Ссылка