Instruction SQL bonne pratique [fermé]
-
07-07-2019 - |
Question
Quelle est la pratique acceptée pour indenter des instructions SQL? Par exemple, considérons l'instruction SQL suivante:
SELECT column1, column2
FROM table1
WHERE column3 IN
(
SELECT TOP(1) column4
FROM table2
INNER JOIN table3
ON table2.column1 = table3.column1
)
Comment cela devrait-il être mis en retrait? Merci beaucoup.
La solution
SELECT column1
, column2
FROM table1
WHERE column3 IN
(
SELECT TOP(1) column4
FROM table2
INNER JOIN table3
ON table2.column1 = table3.column1
)
J'aime avoir tous les ", " devant , de cette manière, je ne les recherche jamais lorsqu'une erreur à la ligne X de l'éditeur SQL.
Ceci est un exemple pour ceux qui n'utilisent pas ce type d'instruction SQL d'écriture. Les deux contiennent une erreur de virgule manquante.
SELECT sdcolumn123
, dscolumn234
, sdcolumn343
, ffcolumn434
, sdcolumn543
, bvcolumn645
vccolumn754
, cccolumn834
, vvcolumn954
, cvcolumn104
FROM table1
WHERE column3 IN
(
...
)
SELECT sdcolumn123, dscolumn234, asdcolumn345, dscolumn456, ascolumn554, gfcolumn645 sdcolumn754, fdcolumn845, sdcolumn954, fdcolumn1054
FROM table1
WHERE column3 IN
(
...
)
J'ai trouvé plus facile et plus rapide le premier exemple. J'espère que cet exemple montre davantage mon point de vue.
Autres conseils
SELECT column1, column2
FROM table
WHERE column3 IN (
SELECT TOP(1) column4
FROM table2
INNER JOIN table3 ON table2.column1 = table3.column1
)
C'est assez court et facile à lire. Je ferais des ajustements s'il y avait plus de colonnes sélectionnées ou plus de conditions de jointure.
Je ne suis pas sûr qu'il existe une pratique acceptée, mais voici comment procéder:
SELECT
column1,
column2
FROM
table1
WHERE
column3 IN
(
SELECT TOP(1)
column4
FROM
table2
INNER JOIN
table3
ON table2.column1 = table3.column1
)
J'aime avoir " rivières " de l'espace dans le code. Cela facilite un peu la numérisation.
SELECT column1,
column2
FROM table1
WHERE column3 IN (SELECT column4
FROM table2
JOIN table3
ON table2.column1 = table3.column1);
J'aime bien la façon dont jalbert aligne les mots-clés sur leur droite. J'ajouterais également que j'aime les AND et les OR situés à gauche (certaines personnes les placent à droite.) De plus, j'aime bien aligner mes signes égal lorsque cela est possible.
SELECT column1,
column2
FROM table1, table2
WHERE table1.column1 = table2.column4
AND table1.col5 = "hi"
OR table2.myfield = 678
Ceci est ma méthode personnelle. En fonction de la durée de la condition de jointure, je l'indique parfois sur la ligne ci-dessous.
SELECT
column1,
column2
FROM
table1
WHERE
column3 IN (
SELECT TOP(1)
column4
FROM
table2
INNER JOIN table3 ON table2.column1 = table3.column1
)
SELECT
column1,
column2
FROM
table1
WHERE
column3 IN (
SELECT TOP(1)
column4
FROM
table2
INNER JOIN table3
ON table2.column1 = table3.column1 -- for long ones
)
J'ai écrit pour notre boutique un code standard extrêmement biaisé en matière de lisibilité / "découvrabilité". (ce dernier étant principalement utile dans les instructions insert-select):
SELECT
column1,
column2
FROM
table1
WHERE
column3 IN
(
SELECT TOP(1)
column4
FROM
table2
INNER JOIN table3 ON table2.column1 = table3.column1
)
Sur des requêtes plus complexes, son utilité devient plus évidente:
SELECT
Column1,
Column2,
Function1
(
Column1,
Column2
) as Function1,
CASE
WHEN Column1 = 1 THEN
a
ELSE
B
END as Case1
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.column12 = t2.column21
WHERE
(
FilterClause1
AND FilterClause2
)
OR
(
FilterClause3
AND FilterClause4
)
Une fois que vous avez migré vers des systèmes avec plus d'une jointure commune dans la plupart de vos requêtes, mon expérience m'a montré que l'utilisation de l'espace vertical est votre meilleur ami avec un code SQL complexe.
Si vous avez une longue instruction SQL que vous souhaitez reformater sans taper ni tabuler, vous pouvez l'insérer dans de ce site Web et obtenez un résultat bien formaté. Vous pouvez essayer différents formats pour voir ce qui rend votre texte le plus lisible.
Modifier: Je crois que cet est l'emplacement 2014 du formateur SQL.
Le formatage SQL est un domaine dans lequel il y a beaucoup de divergence et de désaccord ... Mais avant, j'aime me concentrer sur la lisibilité et penser que quoi que vous fassiez, vous conformer systématiquement à toutes les règles qui réduisent la lisibilité est, comme l'ancien cliché va, une "consistance stupide" ("La consistance insensée est un hobgobelin pour les esprits simples")
Donc, au lieu de les appeler règles, voici quelques lignes directrices. Pour chaque clause majeure dans une instruction SQL (Sélectionner, Insérer, Supprimer, De, Où, Avoir, Grouper par, Commander par, il se peut qu'il en manque quelques-unes) devrait être FACILEMENT identifiable. Je les indente donc généralement au plus haut niveau, même les uns avec les autres. Ensuite, dans chaque article, j'indente uniformément la sous-structure logique suivante ... et ainsi de suite. Mais je me sens libre de changer (et le fais souvent) de changer de modèle si, dans un cas donné, il serait plus lisible de le faire ... Les déclarations de cas complexes sont un bon exemple. Comme tout ce qui nécessite un défilement horizontal réduit considérablement la lisibilité, j’écris souvent des expressions de casse complexes (imbriquées) sur plusieurs lignes. Lorsque je le fais, j’essaie de conserver le début d’une telle instruction en tenant compte de son emplacement logique dans l’instruction SQL, et d’indenter le reste des lignes d’instruction de quelques caractères plus loin ...
Le code de base de données SQL existe depuis longtemps, car auparavant, les ordinateurs étaient en minuscules, il existe donc une préférence historique pour les mots clés de casse supérieure, mais je préfère la lisibilité à la tradition ... (et chaque outil que j'utilise code couleur) mots clés maintenant quand même)
J'utiliserais également les alias de table pour réduire la quantité de texte que l'œil doit analyser afin de mémoriser la structure de la requête, tant que les alias ne créent pas de confusion. Dans une requête avec moins de 3 ou 4 tables, les alias à caractère unique conviennent, j'utilise souvent la première lettre de la table si toutes les tables commencent par une lettre différente ... à nouveau, ce qui contribue le plus à la lisibilité. Enfin, si votre base de données le prend en charge, de nombreux mots clés sont facultatifs (tels que "Inner", "Outer", "As" pour les alias, etc.) "Into". (à partir de Insert Into) est facultatif sur Sql Server - mais pas sur Oracle) Soyez donc prudent lorsque vous utilisez ce code si votre code doit être indépendant de la plate-forme ...
Votre exemple, j'écrirais comme:
Select column1, column2
From table1 T1
Where column3 In (Select Top(1) column4
From table2 T2
Join table3 T3
On T2.column1 = T3.column1)
Ou
Select column1, column2
From table1 T1
Where column3 In
(Select Top(1) column4
From table2 T2
Join table3 T3
On T2.column1 = T3.column1)
S'il y a beaucoup plus de colonnes dans la clause select, j'indenterais la deuxième ligne et les lignes suivantes ... Je n'adhère généralement PAS à un type de règle strict (une colonne par ligne), car le défilement verbal est presque aussi mauvais pour la lisibilité. défilement horizontal, en particulier si seules les dix premières colonnes de l’écran contiennent du texte)
Select column1, column2, Col3, Col4, column5,
column6, Column7, isNull(Column8, 'FedEx') Shipper,
Case Upper(Column9)
When 'EAST' Then 'JFK'
When 'SOUTH' Then 'ATL'
When 'WEST' Then 'LAX'
When 'NORTH' Then 'CHI' End HubPoint
From table1 T1
Where column3 In
(Select Top(1) column4
From table2 T2
Join table3 T3
On T2.column1 = T3.column1)
Formatez le code de la manière qui le rend le plus lisible ...
J'aime avoir les différentes parties de ma requête alignées verticalement. J'ai tendance à utiliser une taille de tabulation de 8 espaces pour SQL qui semble bien fonctionner.
SELECT column1,
column2
FROM table1
WHERE column3 IN
(
SELECT TOP(1) column4
FROM table2
INNER JOIN table3
ON table2.column1 = table3.column1
)
Exemple d'indentation d'un SQL très très très complexe:
SELECT
produtos_cesta.cod_produtos_cesta,
produtos.nome_pequeno,
tab_contagem.cont,
produtos_cesta.sku,
produtos_kits.sku_r AS sku_kit,
sku_final = CASE
WHEN produtos_kits.sku_r IS NOT NULL THEN produtos_kits.sku_r
ELSE produtos_cesta.sku
END,
estoque = CASE
WHEN produtos2.estoque IS NOT NULL THEN produtos2.estoque
ELSE produtos.estoque
END,
produtos_cesta.unidades as unidades1,
unidades_x_quantidade = CASE
WHEN produtos.cod_produtos_kits_tipo = 1 THEN CAST(produtos_cesta.quantidade * (produtos_cesta.unidades / tab_contagem.cont) * produtos_kits.quantidade AS int)
ELSE CAST(produtos_cesta.quantidade * produtos_cesta.unidades AS int)
END,
unidades = CASE
WHEN produtos.cod_produtos_kits_tipo = 1 THEN produtos_cesta.unidades / tab_contagem.cont * produtos_kits.quantidade
ELSE produtos_cesta.unidades
END,
unidades_parent = produtos_cesta.unidades,
produtos_cesta.quantidade,
produtos.controla_estoque,
produtos.status
FROM
produtos_cesta
INNER JOIN produtos
ON (produtos_cesta.sku = produtos.sku)
INNER JOIN produtos_pacotes
ON (produtos_cesta.sku = produtos_pacotes.sku)
INNER JOIN (
SELECT
produtos_cesta.cod_produtos_cesta,
cont = SUM(
CASE
WHEN produtos_kits.quantidade IS NOT NULL THEN produtos_kits.quantidade
ELSE 1
END
)
FROM
produtos_cesta
LEFT JOIN produtos_kits
ON (produtos_cesta.sku = produtos_kits.sku)
LEFT JOIN produtos
ON (produtos_cesta.sku = produtos.sku)
WHERE
shopper_id = '" + mscsShopperId + @"'
GROUP BY
produtos_cesta.cod_produtos_cesta,
produtos_cesta.sku,
produtos_cesta.unidades
)
AS tab_contagem
ON (produtos_cesta.cod_produtos_cesta = tab_contagem.cod_produtos_cesta)
LEFT JOIN produtos_kits
ON (produtos.sku = produtos_kits.sku)
LEFT JOIN produtos as produtos2
ON (produtos_kits.sku_r = produtos2.sku)
WHERE
shopper_id = '" + mscsShopperId + @"'
GROUP BY
produtos_cesta.cod_produtos_cesta,
tab_contagem.cont,
produtos_cesta.sku,
produtos_kits.sku_r,
produtos.cod_produtos_kits_tipo,
produtos2.estoque,
produtos.controla_estoque,
produtos.estoque,
produtos.status,
produtos.nome_pequeno,
produtos_cesta.unidades,
produtos_cesta.quantidade,
produtos_kits.quantidade
ORDER BY
produtos_cesta.sku,
produtos_cesta.unidades DESC
Comme la plupart des personnes ci-dessus ont aligné les noms des colonnes de retour, je trouve qu'aligner les noms des tables et les conditions facilite beaucoup la lisibilité.
SELECT
column1,
column2
FROM
table1
WHERE
column3 IN
(
SELECT TOP(1)
column4
FROM
table2 INNER JOIN
table3 ON table2.column1 = table3.column1
)
Et pour quand les conditions de jointure deviennent longues.
SELECT
Column1,
Column2
FROM
Table1 JOIN
Table2 ON
Table1.Column3 = Table2.Column4 JOIN
Table3 ON
Table2.Column1 = Table3.Column1 and
Table2.ColumnX = @x and
Table3.ColumnY = @y
WHERE
Condition1=xxx and
Condition2=yyy and
(
Condition3=aaa or
Condition4=bbb
)
Voici ce que je ressens:
select column1, column2
from table1
where (column3 in (
select top(1) column4
from table2
inner join table3
on (table2.column1 = table3.column1)
))
;
- Tout ce qui est en minuscule, car il est plus facile de lire les caractères minuscules (et nous avons du surlignage de code pour mettre en valeur les mots-clés) et aussi plus facile à taper
- Toutes les restrictions ou options relatives à un mot clé (par exemple, de la sélection ou de la jointure) sont indentées pour indiquer leur dépendance vis-à-vis du mot clé externe
- Le crochet de fermeture est au même niveau d'indentation que l'ouverture où
- Utilisez des crochets pour les clauses where et on afin d'améliorer la lisibilité
- Demandez au point-virgule de fermer l'instruction select en même temps pour permettre la distinction de plusieurs instructions (si vous avez besoin d'un point-virgule dans votre langage, comme le fait SAS PROC SQL)
- Il est toujours assez compact et ne s'étend pas sur toute la page
Bien sûr, cela dépend de vos préférences personnelles. Et si cela se fait en équipe, c'est quelque chose qui devrait être convenu entre les membres pour des raisons de cohérence. Mais ce serait ma préférence:
SELECT column1, column2
FROM table1
WHERE column3 IN(SELECT TOP(1) column4
FROM table2
INNER JOIN table3 ON
table2.column1 = table3.column1
)
Je formaterais comme ceci:
SELECT
column1,
column2
FROM
table1
WHERE
column3 IN (SELECT TOP(1)
column4
FROM
table2
INNER JOIN table3 ON table2.column1 = table3.column1)
ou comme ceci:
SELECT
column1,
column2
FROM
table1
WHERE
column3 IN (SELECT TOP(1) column4
FROM table2
INNER JOIN table3 ON table2.column1 = table3.column1)
Ceci est ma préférence normale:
....SELECT column1
........,column2
....FROM table1
....WHERE column3 IN (
........SELECT TOP(1) column4
........FROM table2
........INNER JOIN table3
............ON table2.column1 = table3.column1
....)
Bien que stackoverflow gâche la mise en forme avec un espace supplémentaire, je mets donc quelques périodes pour que vous puissiez voir la mise en forme réelle ...
Je viens de le faire passer par mon prettificateur SQL et il est sorti comme ça ....
SELECT column1, column2
FROM table1
WHERE column3 IN
(
SELECT TOP(1) column4
FROM table2
INNER JOIN table3
ON table2.column1 = table3.column1
)
http://extras.sqlservercentral.com/prettifier/prettifier.aspx
..... Mais je n'ai pas trouvé de moyen d'obtenir des couleurs dans StackOverflow.
Oui, c'est assez subjectif ... Mais voici mes 2 centimes:
SELECT
Column1,
Column2
FROM Table1
WHERE
Column3 IN (
SELECT Column4
FROM Table2
JOIN Table3 ON
Table2.Column1 = Table3.Column1
)
Mais vraiment, je le réécrirais probablement sans le IN:
SELECT
Column1,
Column2
FROM Table1
JOIN Table2 ON
Table1.Column3 = Table2.Column4
JOIN Table3 ON
Table2.Column1 = Table3.Column1
Mes règles sont les suivantes:
- Capitaliser les mots clés
- Les colonnes vont sur des lignes individuelles, mais les modificateurs SELECT (SELECT TOP 100, SELECT DISTINCT, etc.) ou les colonnes simples (SELECT 1, SELECT Id, SELECT *, etc.) vont sur la même ligne
- Conditions de joint indentées sous la clause JOIN
- Utilisez JOIN pour INNER JOIN (puisqu'il s'agit du commun) et spécifiez pleinement les autres (LEFT OUTER JOIN, FULL OUTER JOIN, etc.)
- Ouvrez les parenthèses sur la même ligne, fermez-les sur une ligne distincte. Si vous avez un alias, celui-ci est associé à une paren proche.
Ce lien est le meilleur que j'ai trouvé. http://www.sqlinform.com/free_online_sw.html
Bien sûr, cela dépend de la requête.
Pour les requêtes simples, un schéma d'indentation très formel est juste un problème supplémentaire et peut réellement rendre le code moins lisible, pas plus. Mais à mesure que la complexité augmente, vous devez commencer à faire preuve de plus de prudence dans la structure de votre déclaration afin de vous assurer qu'elle sera à nouveau lisible ultérieurement.
Je ne sais pas s'il existe une norme, mais j'aime bien le faire de cette façon;
SELECT column1, column2
FROM table1
WHERE column3 IN
(
SELECT TOP(1) column4
FROM table2
INNER JOIN table3
ON table2.column1 = table3.column1
)
parce que je peux mieux lire et analyser le code SQL.
SELECT
Column1,
Column2
FROM
Table1
WHERE
Column3 IN
(
SELECT TOP (1)
Column4
FROM
Table2
INNER JOIN
Table3
ON
Table2.Column1 = Table3.Column1
)
Ce que je fais habituellement est,
print("SELECT column1, column2
FROM table1
WHERE column3 IN (SELECT TOP(1) column4
FROM table2 INNER JOIN
table3 ON table2.column1 = table3.column1)");
C’est une question de goût.
C’est ma préférence.
SELECT
column1
,column2
FROM
table1
WHERE column3 IN (
SELECT TOP(1) column4
FROM
table2
INNER JOIN table3
ON table2.column1 = table3.column1
)
C'est comme ça que nous le ferions ici:
select COLUMN1, COLUMN2, case when COLUMN5 = 'X' and COLUMN6 = 'Y' then 'one' when COLUMN5 in ( 'AAA', 'BBB' ) then 'two' else 'three' end as COLUMN7 from TABLE1 where COLUMN2 in ( select top(1) COLUMN4 from TABLE2 inner join TABLE3 on TABLE2.COLUMN1 = TABLE3.COLUMN1 and TABLE2.COLUMN2 between TABLE3.COLUMN2 and TABLE3.COLUMN3 )
Notre idée est la suivante: conservez les mots-clés SQL en minuscule et mettez tous les éléments qui changent (et donc "plus intéressants"), tels que les noms de table ou de colonne en majuscule. Le code peut sembler un peu "éclaté" Ici, mais cela augmente la lisibilité si vous avez des requêtes complexes avec des noms plus longs (y compris schéma, etc.) beaucoup plus longues que dans cet exemple. Et: indenter tous les objets en fonction de leur "niveau".