Oracle 'Partition Par" et " Row_Number mot-clé
J'ai une requête SQL écrit par quelqu'un d'autre et je suis à essayer de comprendre ce qu'il fait. Quelqu'un peut-il expliquer ce qu'est la Partition By
et Row_Number
mots clés ici et de donner un exemple simple de en action, ainsi que pourquoi vouloir l'utiliser?
Un exemple de partition par:
(SELECT cdt.*,
ROW_NUMBER ()
OVER (PARTITION BY cdt.country_code, cdt.account, cdt.currency
ORDER BY cdt.country_code, cdt.account, cdt.currency)
seq_no
FROM CUSTOMER_DETAILS cdt);
J'ai vu quelques exemples en ligne, ils sont peu trop de profondeur.
Merci d'avance!
Vous devez vous connecter pour publier un commentaire.
PARTITION BY
séparer les ensembles, cela vous permet d'être en mesure de travailler(ROW_NUMBER(),COUNT(),SUM(),etc.) sur l'ensemble lié de façon indépendante.Dans votre requête, l'ensemble composé de lignes avec les mêmes cdt.code_pays, cdt.compte, cdt.de la monnaie. Lorsque vous partition sur ces colonnes et que vous appliquez la fonction ROW_NUMBER sur eux. Les autres colonnes sur ceux de la combinaison/set recevrez un numéro d'ordre à partir de la fonction ROW_NUMBER
Mais cette requête est drôle, si votre partition par certains de données unique et vous mettez un row_number sur elle, il suffit de produire le même nombre. C'est comme faire un ORDER BY sur une partition qui est garanti pour être unique. Exemple, pensez GUID comme combinaison unique de
cdt.country_code, cdt.account, cdt.currency
newid()
produit GUID, donc ce qui doit vous attendre, par cette expression?...Bon, tous les partitionné(aucun n'a été partitionné, chaque ligne est divisée en leur propre ligne) rangées " row_numbers sont tous à 1
Fondamentalement, vous devez partitionner sur les colonnes non unique. COMMANDE PAR sur PLUS de besoin de la PARTITION EN avoir un non-combinaison unique, sinon tous les row_numbers va devenir 1
Un exemple, c'est vos données:
Puis c'est l'analogue de votre requête:
Ce sera la sortie de cette?
Vous voir toi combinaison de HI HO? Les trois premières lignes a combinaison unique, d'où ils sont mis à 1, la B des lignes a même W, d'où les différentes ROW_NUMBERS, de même pour le SALUT C lignes.
Maintenant, pourquoi le
ORDER BY
besoin là-bas? Si le développeur précédent veulent simplement mettre un row_number sur des données similaires (par exemple, HI B, toutes les données sont B-W, B-W), il suffit de faire ceci:Mais hélas, Oracle et Sql Server) ne permet pas de partition sans
ORDER BY
; considérant que, dans Postgresql,ORDER BY
sur la PARTITION est facultatif: http://www.sqlfiddle.com/#!1/27821/1Votre
ORDER BY
sur votre partition de regarder un peu redondant, non pas parce que le développeur précédent de la faute, une base de données il suffit de ne pas permettrePARTITION
sansORDER BY
, il ne pourrait pas en mesure de trouver un bon candidat de la colonne à trier. Si les deux PARTITION PAR des colonnes et l'ORDRE des colonnes sont les mêmes, il suffit de retirer la COMMANDE PAR, mais depuis quelques la base de données ne le permet pas, il vous suffit de faire ceci:Vous ne pouvez pas trouver un bon colonne à utiliser pour le tri des données similaires? Vous pouvez ainsi trier sur le hasard, les données partitionnées en ont le mêmes valeurs de toute façon. Vous pouvez utiliser le GUID par exemple(vous utilisez
newid()
pour SQL Server). Alors qui a la même sortie faite par le développeur précédent, il est regrettable que certains de la base de données ne permet pasPARTITION
sansORDER BY
Si vraiment, il m'échappe et je ne peux pas trouver une bonne raison de mettre un numéro sur les mêmes combinaisons (B-W, B-W dans l'exemple ci-dessus). C'est en donnant l'impression de la base de données ayant des données redondantes. D'une certaine manière m'a rappelé ceci: Comment obtenir un enregistrement unique à partir de la même liste des enregistrements de la table? Aucune contrainte d'unicité dans le tableau
Il ressemble vraiment à des arcanes de voir une PARTITION avec la même combinaison de colonnes avec COMMANDE PAR, ne peut pas facilement en déduire le code de l'intention.
Test en direct: http://www.sqlfiddle.com/#!3/27821/6
Mais comme dbaseman ont remarqué aussi, il est inutile de partition et de l'ordre sur les mêmes colonnes.
Vous avez un ensemble de données comme ceci:
Alors vous PARTITION PAR hi,ho, et puis vous commandez PAR hi,ho. Il n'y a pas de sens de numérotation des données similaires 🙂 http://www.sqlfiddle.com/#!3/29ab8/3
De sortie:
Voir? Pourquoi faut-il mettre les numéros de ligne sur la même combinaison? Ce qui vous permettra d'analyser sur le triple A,X, double B,Y, double C,Z? 🙂
Vous avez juste besoin d'utiliser la PARTITION de non-colonne unique, alors vous triez sur la non-unique colonne(s) unique-ing colonne. Exemple sera plus clair:
PARTITION BY hi
fonctionne sur la non unique colonne, puis sur chaque partitionné colonne, vous commandez sur sa colonne unique(ho),ORDER BY ho
De sortie:
Cet ensemble de données a plus de sens
Test en direct: http://www.sqlfiddle.com/#!3/d0b44/1
Et ce qui est similaire à votre requête avec les mêmes colonnes sur les deux PARTITION BY et ORDER BY:
Et c'est la sortie:
Voir? a aucun sens?
Test en direct: http://www.sqlfiddle.com/#!3/d0b44/3
Enfin, ce peut être le droit de requête:
Qui sélectionne le numéro de ligne par code de pays, le compte et la monnaie. Ainsi, les lignes de code de pays "NOUS", le compte "XYZ" et la devise "$USD" vont obtenir un numéro de ligne affecté à partir de 1-n; il en va de même pour toute autre combinaison de ces colonnes dans le jeu de résultats.
Cette requête est assez drôle, parce que le commande par clause ne fait absolument rien. Toutes les lignes de chaque partition ont le même code de pays, le compte et la monnaie, donc il n'y a pas de point de commande par ces colonnes. L'ultime ligne de numéros attribués dans cette requête particulière devra donc être imprévisible.
Espère que ça aide...
J'utilise souvent la fonction row_number() comme un moyen rapide de jeter des enregistrements en double de mon select. Il suffit d'ajouter une clause where. Quelque chose comme...
Je sais que c'est un vieux thread mais la PARTITION est l'équivalent de GROUPE PAR pas de COMMANDE PAR. ORDER BY dans cette fonction . . . COMMANDE PAR. C'est juste une façon de créer de l'unicité de la redondance par l'ajout d'un numéro de séquence. Ou vous pouvez éliminer les autres enregistrements redondants par la clause where lorsqu'une référence est un alias de colonne pour la fonction. Cependant, DISTINCT dans l'instruction SELECT ne serait probablement faire la même chose à cet égard.