Может ли кто-нибудь объяснить мне промежуточный итог и самосоединение SQL в этом руководстве? - PullRequest
0 голосов
/ 27 марта 2010

Я читал здесь урок: http://www.1keydata.com/sql/sql-running-totals.html и все это имело смысл, пока вдруг не стало невероятно невероятно сложным, когда он получил ранжирование, медиану, промежуточные итоги и т.д. этот запрос приводит к промежуточному итогу? Спасибо!

Ответы [ 4 ]

4 голосов
/ 27 марта 2010

До того, как я начал, я не видел этого раньше, и это не выглядит ужасно понятным способом подвести итоги.

Хорошо, вот запрос из учебника:

SELECT a1.Name, a1.Sales, SUM(a2.Sales) Running_Total
FROM Total_Sales a1, Total_Sales a2
WHERE a1.Sales <= a2.sales or (a1.Sales=a2.Sales and a1.Name = a2.Name)
GROUP BY a1.Name, a1.Sales
ORDER BY a1.Sales DESC, a1.Name DESC;

И образец вывода

Name    Sales   Running_Total
Greg     50     50
Sophia    40    90
Stella    20    110
Jeff      20    130
Jennifer  15    145
John      10    155

Простая часть этого запроса отображает данные о продажах для каждого сотрудника. Все, что мы делаем, это выбираем name и sales у каждого сотрудника и упорядочиваем их по сумме продажи (по убыванию). Это дает нам наш базовый список.

Теперь для промежуточного итога мы хотим, чтобы каждая строка уже отображалась. Итак, мы объединяем таблицу против себя, в каждой строке, которая уже была бы отображена:

WHERE a1.Sales <= a2.sales or (a1.Sales=a2.Sales and a1.Name = a2.Name)

Затем мы используем агрегатную функцию SUM и группируем соответственно. Хороший способ понять это, если вы посмотрите, что произойдет, если вы не используете групповую функцию. Строка «София» будет выглядеть так:

Name    A1.Sales    A2.Sales
Sophia  40          50
Sophia    40         40

Заметьте, как мы получили продажи Грэга? Группа подведет итоги, и вуаля!

Надеюсь, это поможет. Джо

0 голосов
/ 04 августа 2015

Я также получаю тот же неверный вывод, что и Боб, выше которого текущие итоги разбиваются на Стеллу и Джеффа, у которых тот же номер продаж. Я использую SQL Server 2014 Management Studio Express. Я не думаю, что решение сайта на самом деле правильно. Я сделал объединение, основанное на имени, а не на продажах, и придумал это, которое дает правильный промежуточный итог:

select a1.name
, a1.sales
, sum(a2.sales) 'running_total'
from #total_sales a1
inner join #total_sales a2 on a1.name <= a2.name 
group by a1.name, a1.sales
order by sum(a2.sales);

Урожайность:

name      sales  running_total
Stella    20     20
Sophia    40     60
John      10     70
Jennifer  15     85
Jeff      20     105
Greg      50     155

Вы также можете сделать вариант ниже, если вам неудобно сортировать по совокупности. Это меняет порядок, но промежуточный итог все еще корректен:

select a1.name
, a1.sales
, sum(a2.sales) 'running_total'
from #total_sales a1
inner join #total_sales a2 on a1.name >= a2.name 
group by a1.name, a1.sales
order by a1.name;

Урожайность:

name     sales  running_total
Greg     50     50
Jeff     20     70
Jennifer 15     85
John     10     95
Sophia   40     135
Stella   20     155
0 голосов
/ 15 января 2014

Приведенный выше SQL дает другой результат на Sybase (ASE 15). Я думаю, что причина в том, что «порядок по» не применяется до времени отображения. Вот SQL и результат:

drop table Total_Sales
go
create table Total_Sales
(
    Name char(15),
    Sales  int
)

INSERT INTO Total_Sales VALUES( 'John', 10 )
INSERT INTO Total_Sales VALUES( 'Jennifer', 15)
INSERT INTO Total_Sales VALUES('Stella', 20 )
INSERT INTO Total_Sales VALUES('Sophia', 40 )
INSERT INTO Total_Sales VALUES('Greg', 50 )
INSERT INTO Total_Sales VALUES('Jeff', 20 )

SELECT a1.Name, a1.Sales, SUM(a2.Sales) Running_Total 
FROM Total_Sales a1, Total_Sales a2 
WHERE a1.Sales <= a2.Sales or (a1.Sales=a2.Sales and a1.Name = a2.Name) 
GROUP BY a1.Name, a1.Sales 
ORDER BY a1.Sales DESC, a1.Name DESC

Результат:

Name           Sales Running_Total   
Greg            50  50   
Sophia          40  90   
Stella          20  130 --note that two running totals are the same! 
Jeff            20  130  
Jennifer        15  145  
John            10  155  

Bob

0 голосов
/ 27 марта 2010

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

Затем он группирует поля в левой части объединения и суммирует строки, к которым мы присоединяемся, таким образом, промежуточный итог. Чтобы увидеть, как это работает, вы можете запустить его без суммирования и группировки, чтобы увидеть возвращенные необработанные результаты.

...