|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||||
|
Membre émérite
![]() Inscription : mars 2002 Messages : 825 ![]() |
Bonjour.
J'aimerai refaire un point avec les habitués du SQL et de la théorie des ensembles. J'ai actuellement un problème avec mon moteur de base de données. (HyperFile) Je vais d'abord poser le contexte :
Mon problème maintenant : La requête Code :
C'est à dire :
Code :
Qui a raison ? |
||||||
|
|
00
|
|
|
#2 | ||||||
|
Membre chevronné
![]() Administrateur de base de données Inscription : août 2009 Messages : 404 ![]() |
Bonjour,
Je cite Wikipédia, sur l'opération d'union dans la théorie des ensembles: Citation:
Le fait est que le langage SQL permet de manipuler des tables (ou relation) qui contiennent des doublons ! Un ensemble par définition ne peux pas contenir de doublons ! Il n'y a pas de doublons dans l'ensemble des entiers naturels. Par défaut en SQL, l'opérateur SELECT permet donc de retourner des doublons. C'est une énorme erreur, un délit. C'est comme si, lorsqu'on écrit simplement "SELECT ..." on utilisait implicitement: L'opérateur UNION agit en respectant la théorie relationnel, car on est certain que le résultat d'une UNION de deux tables ne retournera jamais de doublons. C'est tout à fait correct. Citation:
Code :
Code :
SELECT FactureLigne_Qte20, FactureLigne_PxNetHT FROM FactureLigne Soit vous avez besoins de ces doublons dans le résultat de l'opération d'union qui comporte cette table en opérande, dans ce cas utilisez UNION ALL, soit vous n'en avez pas besoin, et il est tout à fait normal qu'UNION ne retourne pas ces doublons. J'espère avoir était clair et avoir répondu à la question. |
||||||
|
|
10
|
|
|
#3 | |||||||
|
Membre émérite
![]() Inscription : mars 2002 Messages : 825 ![]() |
Citation:
Puis-je prendre un jeu de données, pour faciliter ma compréhension ? FactureLigne : 4 enreg [ Qte20 | PxNetHT ]
J'ai donc 4 lignes, mais 3 valeurs distinctes par table. Et la ligne [ 6 | 35 ] se retrouve dans chacun des deux ensembles. La requête Code :
La même requête sans les DISTINCT renvoie d'ailleurs exactement les mêmes lignes. Est-ce que mon raisonnement est mauvais? Pour moi, la requête Code :
|
|||||||
|
|
00
|
|
|
#4 | |||||
|
Membre chevronné
![]() Administrateur de base de données Inscription : août 2009 Messages : 404 ![]() |
Citation:
Sur SQL Server 2005 : Code :
Code :
|
|||||
|
|
10
|
|
|
#5 | ||||
![]() ![]() |
Bowen, apparemment, tu n'as pas compris l'explication d'Oishiiii.
Citation:
Comme l'opération UNION supprime les doublons, l'union de la table FactureLigne avec une table vide supprime les doublons de la table FactureLigne et revient donc à faire une requête SELECT DISTINCT sur la table FactureLigne toute seule. Il est donc normal que le résultat de la requête UNION ne te retourne que 256 lignes. Dans l'ordre, le SGBD exécute les deux sous-requêtes, soit une liste de 316 + 0 = 316 lignes, puis il supprime les 60 doublons de cette liste et tu n'as plus que 256 lignes. Faisons-le avec ton dernier exemple : Citation:
[ Qte20 | PxNetHT ]
Ensuite il supprime les lignes de la liste en double :
Résultat final :
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique. Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework... « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau) À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française ! Linuxiens, comptez-vous ! |
||||
|
10
|
|
|
#6 |
|
Membre émérite
![]() Inscription : mars 2002 Messages : 825 ![]() |
Si si, j'avais bien compris... que je n'utilisais pas la bonne méthode. Ce que je voulais, c'était ne supprimer que les doublons créés par l'intersection des deux fichiers.
Chose que je croyais possible directement par un UNION. Bref, j'ai encore dit une bêtise... Je vous remercie en tous cas pour tous ces éclaircissements. Ma requête correcte (dans mon code, donc dans une configuration un peu moins "scolaire") comprends donc un UNION ALL maintenant. Merci, à vous, ça fait du bien de revenir sur les fondamentaux.
|
|
|
00
|
|
|
#7 |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 953 ![]() |
Un doublon étant un doublon il est impossible de le distinguer. Que les doublons soit dans une table ou l'autre, une fois l'union faite vous serez incapable de voir d'où viennent vos doublons.
Donc l'opérateur UNION dédoublonne TOUT ! Votre erreur, votre mauvaise interprétation vient du fait que vous ne savez pas travailler en ensembliste et pensez itératif... C'est une erreur courante ! Pensez qu'une ensembliste il n'y a pas de notion d'ordre. Une fois dans un résultat il n'est pas possible de savoir d'ou vient une ligne ! A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
00
|
Copyright © 2000-2012 - www.developpez.com