Quelqu'un peut-il expliquer le total en cours d'exécution et SQL autojointure dans ce tutoriel pour moi?

StackOverflow https://stackoverflow.com/questions/2529367

  •  22-09-2019
  •  | 
  •  

Question

Je suis en train de lire sur le tutoriel ici: http: //www.1keydata .com / sql / sql-running-totals.html et tout fait sens jusqu'à ce qu'il soudainement se incroyablement extrêmement ridiculement compliqué quand il est arrivé à classer, la médiane, les totaux en cours d'exécution, etc. quelqu'un peut-il expliquer en anglais clair comment cette les résultats de la requête dans un total en cours d'exécution? Merci!

Était-ce utile?

La solution

Avant de commencer, je ne l'ai pas vu cela avant et il ne ressemble pas à une manière terriblement compréhensible pour accomplir un total en cours d'exécution.

D'accord, voici la requête du tutoriel:

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;

Et la sortie de l'échantillon

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

La partie simple de cette requête affiche les données de vente pour chaque employé. Tout ce que nous faisons est la sélection name et sales de chaque employé et de les commander par le montant de la vente (descendant). Cela nous donne notre liste de base.

Nous voulons maintenant pour le total en cours d'exécution, chaque ligne qui a déjà été affiché. Donc, nous nous associons à la table contre lui-même, sur chaque ligne qui aurait déjà été affiché:

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

Ensuite, nous utilisons la fonction d'agrégation SUM et le groupe en conséquence. Une bonne façon de comprendre est que si vous regardez ce qui se passerait si vous n'avez pas utilisé la fonction de groupe. La ligne « Sophia » ressemblerait à ceci:

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

Remarquez comment nous avons obtenu la ligne de vente de Greg? Le groupe somme, et le tour est joué!

L'espoir qui aide. Joe

Autres conseils

La première table se joint à lui-même, la jointure entraînant un nombre x de lignes, où x est le nombre de lignes qui ont la baisse des ventes totales que lui-même, ou le nom de la ligne est la même (toutes ces ventes avant la ligne que nous regardons, lors de la commande par le montant des ventes).

Il a ensuite des groupes sur les champs de la partie gauche de la jointure et résume les lignes que nous joignons à, donc un total en cours d'exécution. Pour voir comment cela fonctionne, vous pouvez l'exécuter sans la somme et le regroupement, pour voir les résultats bruts sont retournés.

Le SQL ci-dessus donne un résultat différent sur Sybase (ASE 15). Je pense que la raison est que la « commande par » n'est pas appliquée jusqu'à ce que le temps d'affichage. Voici le SQL et le résultat:

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

Résultat:

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

Je reçois aussi la même sortie incorrecte comme Bob ci-dessus où les pauses de total vers le bas à Stella & Jeff, qui ont le même nombre de ventes. J'utilise SQL Server 2014 Management Studio Express. Je ne pense pas que la solution du site est correcte. Je ne la jointure basée sur le nom plutôt que sur les ventes et est venu avec ceux-ci, qui produisent un total de fonctionnement correct:

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);

Rendements:

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

Vous pouvez également faire la variante ci-dessous si vous êtes mal à l'aise sur un total de tri. Il change l'ordre, mais le total en cours d'exécution est toujours correcte:

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;

Rendements:

name     sales  running_total
Greg     50     50
Jeff     20     70
Jennifer 15     85
John     10     95
Sophia   40     135
Stella   20     155
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top