Je trouve très difficile d'écrire des requêtes SQL complexes impliquant des jointures entre plusieurs tables (au moins 3-4) et impliquant plusieurs conditions imbriquées. Les requêtes que l'on me demande d'écrire sont facilement décrites par quelques phrases, mais peuvent nécessiter une quantité de code trompeuse. Je me trouve souvent en train d'utiliser des vues temporaires pour écrire ces requêtes, qui ressemblent à une béquille. Quels conseils pouvez-vous fournir pour faciliter ces requêtes complexes? Plus précisément, comment puis-je décomposer ces requêtes en étapes que je dois suivre pour écrire le code SQL?
Notez que je suis le code SQL que l’on me demande d’écrire fait partie des devoirs d’un cours de base de données. Je ne souhaite donc pas de logiciel qui fera le travail à ma place. Je veux réellement comprendre le code que j'écris.
Plus de détails techniques:
- La base de données est hébergée sur un serveur PostgreSQL qui s'exécute sur la machine locale.
- La base de données est très petite: il n'y a pas plus de sept tables et la plus grande contient moins de 50 lignes.
- Les requêtes SQL sont transmises sans modification au serveur, via LibreOffice Base.
Réponses:
Je me base principalement sur le fait d’essayer d’obtenir la "bonne" réponse, de sorte que vous pourriez découvrir quelques problèmes de performances. Inutile d'accélérer une requête incorrecte.
Comprendre les relations entre les tables - la plupart seront un à plusieurs. Connaître le "plusieurs" table. Identifiez les champs requis pour vos jointures.
Pensez aux scénarios de participation à GAUCHE - Sélectionnez tous les employés et leur salaire depuis le mois dernier. Et s'ils ne recevaient pas de salaire le mois dernier?
Connaître le jeu de résultats: 1) Dans une feuille de calcul, entrez manuellement au moins un enregistrement correct pour votre requête. 2) Ecrivez la requête sous une forme assez simple pour identifier le nombre d'enregistrements à renvoyer. Utilisez les deux pour tester votre requête afin de vous assurer que la jonction d'une nouvelle table ne modifie pas le résultat.
Découpez votre requête en parties gérables - Vous n'avez pas à l'écrire en une fois. Les requêtes complexes peuvent parfois être simplement un ensemble de requêtes simples.
Méfiez-vous des niveaux d'agrégation mixtes : si vous devez mettre des valeurs mensuelles, trimestrielles et cumulatives dans le même ensemble de résultats, vous devrez les calculer séparément dans des requêtes groupées sur des valeurs différentes.
Sachez quand joindre UNION Il est parfois plus facile de diviser des sous-groupes en leurs propres déclarations sélectionnées. Si vous avez une table mélangée avec des gestionnaires et d'autres employés, et que vous devez faire dans chaque colonne des instructions Case basées sur l'appartenance à l'un de ces groupes, il peut s'avérer plus simple d'écrire une requête de gestionnaire et de la lier à une requête d'employé. Chacun contiendrait sa propre logique. Devoir inclure des éléments de différentes tables dans différentes lignes est une utilisation évidente.
Formules complexes / imbriquées - Essayez d'indenter de manière cohérente et n'ayez pas peur d'utiliser plusieurs lignes. "CASE WHEN CASE WHEN CASE WHEN" va vous rendre fou. Prenez le temps de bien réfléchir. Enregistrez les calculs complexes pour la fin. Obtenez les enregistrements corrects sélectionnés en premier. Ensuite, vous attaquez des formules complexes en sachant que vous travaillez avec les bonnes valeurs. Voir les valeurs utilisées dans les formules vous aidera à repérer les zones dans lesquelles vous devez prendre en compte les valeurs NULL et où gérer l'erreur de division par zéro.
Testez souvent lorsque vous ajoutez de nouvelles tables pour vous assurer que vous obtenez toujours le jeu de résultats souhaité et que vous savez quelle jointure ou quelle clause est coupable.
la source
L’indentation serait la première chose à faire, si vous ne le faites pas déjà. Non seulement il est utile même avec des requêtes simples, mais il est crucial pour les jointures et les requêtes un peu plus complexes qu’un
select top 1 [ColumnName] from [TableName]
.Une fois mis en retrait correctement, rien n’interdit d’ ajouter des commentaires dans la requête elle-même, le cas échéant. Ne les utilisez pas trop: si le code est suffisamment explicite, ajouter des commentaires nuira à la clarté du code. Mais ils sont toujours les bienvenus pour les parties moins explicites de la requête.
Notez que des requêtes plus longues (y compris des requêtes avec des commentaires) signifieraient une utilisation plus importante de la bande passante entre votre serveur d'applications et votre serveur de base de données. Notez également que si vous travaillez sur un produit à l'échelle de Google avec une quantité énorme de requêtes par seconde, nécessitant des performances et une utilisation des ressources exceptionnelles, la taille ajoutée par les commentaires ne changera rien pour vous en termes de performances.
Appliquer le même style sur les tableaux, les colonnes, etc. facilite également la lisibilité. Lorsqu'une base de données héritée possède les tables
PRODUCT
,users
,USERS_ObsoleteDONT_USE
,PR_SHIPMENTS
etHRhbYd_UU
, quelqu'un fait quelque chose de très mal.L'application du même style sur les requêtes est également importante. Par exemple, si vous écrivez des requêtes pour Microsoft SQL Server et que vous avez décidé d'utiliser
[TableName]
plutôt que deTableName
rester, respectez-le. Si vous passez à une nouvelle ligne après unselect
, ne le faites pas dans seulement la moitié de vos requêtes, mais dans toutes.Ne pas utiliser
*
, sauf s’il existe de fortes raisons de le faire (commeif exists(select * from [TableName] where ...)
dans Microsoft SQL Server). Cela*
a non seulement un impact négatif sur les performances de certaines (sinon de la plupart) des bases de données, mais n’est pas non plus utile pour le développeur qui utilise votre requête. De la même manière, un développeur doit accéder aux valeurs par nom, jamais par index.Enfin, pour les sélections, il n’ya rien de mal à fournir une vue . Pour toute autre chose, les procédures stockées peuvent également être utilisées en fonction du projet et des personnes¹ avec lesquelles vous travaillez².
¹ Certaines personnes détestent les procédures stockées. D'autres ne les aiment pas pour plusieurs raisons (parfaitement valables, du moins pour eux).
² Vos collègues, les autres étudiants, votre professeur, etc.
la source
Un peu dans le noir ici, mais si vous écrivez beaucoup de vues temporaires, vous ne vous êtes peut-être pas encore rendu compte que la plupart des endroits où vous pourriez placer une table dans une instruction SQL pourraient être remplacés par une requête.
Ainsi, plutôt que de joindre la table A à la vue temporaire B, vous pouvez joindre la table A à la requête que vous utilisiez comme vue temporaire B. Par exemple:
Cet exemple est plutôt inutile, mais devrait expliquer la syntaxe.
Pour les vues qui ne sont pas "spéciales" (indexées, partitionnées), le même plan de requête devrait être identique à celui utilisé si vous utilisiez une vue.
En ce qui concerne la rédaction, vous pouvez vérifier chaque élément pour vous assurer que vous obtenez le résultat attendu avant d'écrire l'intégralité de la requête.
Mes excuses si c'est déjà vieux chapeau pour vous.
la source
Au lieu des vues temporaires, utilisez la clause WITH . Cela facilite beaucoup la décomposition de requêtes volumineuses en parties plus petites lisibles.
la source
la source
Comme n'importe quoi d'autre, vous voulez diviser le problème en parties gérables.
Soit dit en passant, vous résolvez des problèmes complexes.
Donc: vous voulez vérifier la sous-requête pour voir qu'elle renvoie vraiment ce que vous voulez avant d'exécuter une requête externe dessus. Vous voulez essayer une jointure minimale de chaque table à laquelle vous vous joignez afin de voir que vous y réfléchissez correctement. Des choses comme ça. Il est tout à fait irréaliste d’espérer taper le tout et obtenir exactement ce que vous voulez.
Une instruction SQL, une fois qu’elle atteint un certain niveau de complexité, est fondamentalement un petit programme en soi. Cela fait une grande différence de vraiment comprendre comment les données sont combinées, sélectionnées, filtrées et sorties.
la source