私はここでチュートリアルを読んでいました:http://www.1keydata.com/sql/sql-running-totals.htmlそして、ランク付け、中央値、実行中の合計になると、突然非常にばかげて信じられないほど複雑になるまで、すべて意味がありました、など。そのクエリがどのように現在の合計になるのか、わかりやすい英語で誰か説明できますか? ありがとう!
4 に答える
始める前に、私はこれを前に見たことがなく、現在の合計を達成するためのひどく理解しやすい方法のようには見えません。
さて、これがチュートリアルからのクエリです:
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
集計関数を使用し、それに応じてグループ化します。これを理解する良い方法は、グループ関数を使用しなかった場合に何が起こるかを調べることです。'Sophia'行は次のようになります。
Name A1.Sales A2.Sales
Sophia 40 50
Sophia 40 40
グレッグの売り上げがどのように得られたかに注目してください。グループはそれを要約し、出来上がり!
お役に立てば幸いです。ジョー
最初のテーブルはそれ自体に結合します。結合の結果、行数はxになります。ここで、xはそれ自体よりも総売上が少ない行の数であるか、行の名前が同じです(つまり、行の前のすべての売上が見ている、販売額で注文した場合)。
次に、結合の左側のフィールドでグループ化し、結合する行を合計して、現在の合計を算出します。それがどのように機能するかを確認するには、合計とグループ化を行わずに実行して、返される生の結果を確認することをお勧めします。
上記の Bob と同じ間違った出力も得られます。現在の合計は、販売数が同じ Stella と Jeff で分類されます。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
上記の SQL は、Sybase (ASE 15) では異なる結果になります。その理由は、表示時間まで「order by」が適用されないためだと思います。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
ボブ