PostgreSQLLa base de données la plus sophistiquée au monde.

Version anglaise

SELECT

SELECT, TABLE, WITH — rĂ©cupĂšre des lignes d'une table ou d'une vue

Synopsis

[ WITH [ RECURSIVE ] requĂȘte_with [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
    [ * | expression [ [ AS ] nom_d_affichage ] [, ...] ]
    [ FROM éléments_from [, ...] ]
    [ WHERE condition ]
    [ GROUP BY expression [, ...] ]
    [ HAVING condition [, ...] ]
    [ WINDOW nom_window AS ( définition_window ) [, ...] ]
    [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
    [ ORDER BY expression [ ASC | DESC | USING opérateur ] [ NULLS { FIRST | LAST } ] [, ...] ]
    [ LIMIT { nombre | ALL } ]
    [ OFFSET début ] [ ROW | ROWS ] ]
    [ FETCH { FIRST | NEXT } [ total ] { ROW | ROWS } ONLY ]
    [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF nom_table [, ...] ] [ NOWAIT ] [...] ]

avec Ă©lĂ©ments_from qui peut ĂȘtre :

    [ ONLY ] nom_table [ * ] [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]
    [ LATERAL ] ( select ) [ AS ] alias [ ( alias_colonne [, ...] ) ]
    nom_requĂȘte_with [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]
    [ LATERAL ] nom_fonction ( [ argument [, ...] ] )
                [ WITH ORDINALITY ] [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]
    [ LATERAL ] nom_fonction ( [ argument [, ...] ] ) [ AS ] alias ( définition_colonne [, ...] )
     [ LATERAL ] nom_fonction ( [ argument [, ...] ] ) AS ( définition_colonne [, ...] )
    [ LATERAL ] ROWS FROM( nom_fonction ( [ argument [, ...] ] ) [ AS ( définition_colonne [, ...] ) ] [, ...] )
                [ WITH ORDINALITY ] [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]
    éléments_from [ NATURAL ] type_jointure éléments_from [ ON condition_jointure | USING ( colonne_jointure [, ...] ) ]

et requĂȘte_with est :

    nom_requĂȘte_with [ ( nom_colonne [, ...] ) ] AS ( select | valeurs | insert | update | delete )

TABLE [ ONLY ] nom_table [ * ]
  

Description

SELECT rĂ©cupĂšre des lignes de zĂ©ro ou plusieurs tables. Le traitement gĂ©nĂ©ral de SELECT est le suivant :

  1. Toutes les requĂȘtes dans la liste WITH sont Ă©valuĂ©es. Elles jouent le rĂŽle de tables temporaires qui peuvent ĂȘtre rĂ©fĂ©rencĂ©es dans la liste FROM. Une requĂȘte WITH qui est rĂ©fĂ©rencĂ©e plus d'une fois dans FROM n'est calculĂ©e qu'une fois (voir la section intitulĂ©e « Clause WITH Â» ci-dessous).

  2. Tous les Ă©lĂ©ments de la liste FROM sont calculĂ©s. (Chaque Ă©lĂ©ment dans la liste FROM est une table rĂ©elle ou virtuelle.) Si plus d'un Ă©lĂ©ment sont spĂ©cifiĂ©s dans la liste FROM, ils font l'objet d'une jointure croisĂ©e (cross-join). (Voir la section intitulĂ©e « Clause FROM Â» ci-dessous.)

  3. Si la clause WHERE est spĂ©cifiĂ©e, toutes les lignes qui ne satisfont pas les conditions sont Ă©liminĂ©es de l'affichage. (Voir la section intitulĂ©e « Clause WHERE Â» ci-dessous.)

  4. Si la clause GROUP BY est spĂ©cifiĂ©e or if there are aggregate function calls, l'affichage est divisĂ© en groupes de lignes qui correspondent Ă  une ou plusieurs valeurs, et aux rĂ©sultats des fonctions d'agrĂ©gat calculĂ©s. Si la clause HAVING est prĂ©sente, elle Ă©limine les groupes qui ne satisfont pas la condition donnĂ©e. (Voir la section intitulĂ©e « Clause GROUP BY Â» et la section intitulĂ©e « Clause HAVING Â» ci-dessous.)

  5. Les lignes retournĂ©es sont traitĂ©es en utilisant les expressions de sortie de SELECT pour chaque ligne ou groupe de ligne sĂ©lectionnĂ©. (Voir la section intitulĂ©e « Liste SELECT Â» ci-dessous.)

  6. SELECT DISTINCT élimine du résultat les lignes en double. SELECT DISTINCT ON élimine les lignes qui correspondent sur toute l'expression spécifiée. SELECT ALL (l'option par défaut) retourne toutes les lignes, y compris les doublons. (cf. DISTINCT Clause ci-dessous.)

  7. En utilisant les opĂ©rateurs UNION, INTERSECT et EXCEPT, l'affichage de plusieurs instructions SELECT peut ĂȘtre combinĂ© pour former un ensemble unique de rĂ©sultats. L'opĂ©rateur UNION renvoie toutes les lignes qui appartiennent, au moins, Ă  l'un des ensembles de rĂ©sultats. L'opĂ©rateur INTERSECT renvoie toutes les lignes qui sont dans tous les ensembles de rĂ©sultats. L'opĂ©rateur EXCEPT renvoie les lignes qui sont prĂ©sentes dans le premier ensemble de rĂ©sultats mais pas dans le deuxiĂšme. Dans les trois cas, les lignes dupliquĂ©es sont Ă©liminĂ©es sauf si ALL est spĂ©cifiĂ©. Le mot-clĂ© supplĂ©mentaire DISTINCT peut ĂȘtre ajoutĂ© pour signifier explicitement que les lignes en doublon sont Ă©liminĂ©es. Notez bien que DISTINCT est lĂ  le comportement par dĂ©faut, bien que ALL soit le dĂ©faut pour la commande SELECT. (Voir la section intitulĂ©e « Clause UNION Â», la section intitulĂ©e « Clause INTERSECT Â» et la section intitulĂ©e « Clause EXCEPT Â» ci-dessous.)

  8. Si la clause ORDER BY est spĂ©cifiĂ©e, les lignes renvoyĂ©es sont triĂ©es dans l'ordre spĂ©cifiĂ©. Si ORDER BY n'est pas indiquĂ©, les lignes sont retournĂ©es dans l'ordre qui permet la rĂ©ponse la plus rapide du systĂšme. (Voir la section intitulĂ©e « Clause ORDER BY Â» ci-dessous.)

  9. Si les clauses LIMIT (ou FETCH FIRST) ou OFFSET sont spĂ©cifiĂ©es, l'instruction SELECT ne renvoie qu'un sous-ensemble de lignes de rĂ©sultats. (Voir la section intitulĂ©e « Clause LIMIT Â» ci-dessous.)

  10. Si la clause FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE ou FOR KEY SHARE est spĂ©cifiĂ©e, l'instruction SELECT verrouille les lignes sĂ©lectionnĂ©es contre les mises Ă  jour concurrentes. (Voir la section intitulĂ©e « Clause de verrouillage Â» ci-dessous.)

Le droit SELECT sur chaque colonne utilisée dans une commande SELECT est nécessaire pour lire ses valeurs. L'utilisation de FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE ou FOR KEY SHARE requiert en plus le droit UPDATE (pour au moins une colonne de chaque table sélectionnée).

ParamĂštres

Clause WITH

La clause WITH vous permet de spĂ©cifier une ou plusieurs sous-requĂȘtes qui peuvent ĂȘtre utilisĂ©es par leur nom dans la requĂȘte principale. Les sous-requĂȘtes se comportent comme des tables temporaires ou des vues pendant la durĂ©e d'exĂ©cution de la requĂȘte principale. Chaque sous-requĂȘte peut ĂȘtre un ordre SELECT, TABLE, VALUES, INSERT, UPDATE ou bien DELETE. Lorsque vous Ă©crivez un ordre de modification de donnĂ©es (INSERT, UPDATE ou DELETE) dans une clause WITH, il est habituel d'inclure une clause RETURNING. C'est la sortie de cette clause RETURNING, et non pas la table sous-jacente que l'ordre modifie, qui donne lieu Ă  la table temporaire lue par la requĂȘte principale. Si la clause RETURNING est omise, l'ordre est tout de mĂȘme exĂ©cutĂ©, mais il ne produit pas de sortie ; il ne peut donc pas ĂȘtre rĂ©fĂ©rencĂ© comme une table par la requĂȘte principale.

Un nom (sans qualification de schĂ©ma) doit ĂȘtre spĂ©cifiĂ© pour chaque requĂȘte WITH. En option, une liste de noms de colonnes peut ĂȘtre spĂ©cifiĂ© ; si elle est omise, les noms de colonnes sont dĂ©duites de la sous-requĂȘte.

Si RECURSIVE est spĂ©cifiĂ©, la sous-requĂȘte SELECT peut se rĂ©fĂ©rencer elle mĂȘme. Une sous-requĂȘte de ce type doit avoir la forme

terme_non_récursif UNION [ ALL | DISTINCT ] terme_récursif
    

oĂč l'auto-rĂ©fĂ©rence rĂ©cursive doit apparaĂźtre dans la partie droite de l'UNION. Seule une auto-rĂ©fĂ©rence rĂ©cursive est autorisĂ©e par requĂȘte. Les ordres de modification rĂ©cursifs ne sont pas supportĂ©s, mais vous pouvez utiliser le rĂ©sultat d'une commande SELECT rĂ©cursive dans un ordre de modification. Voir Section 7.8, « RequĂȘtes WITH (Common Table Expressions) Â» pour un exemple.

Un autre effet de RECURSIVE est que les requĂȘtes WITH n'ont pas besoin d'ĂȘtre ordonnĂ©es : une requĂȘte peut en rĂ©fĂ©rencer une autre qui se trouve plus loin dans la liste (toutefois, les rĂ©fĂ©rences circulaires, ou rĂ©cursion mutuelle, ne sont pas implĂ©mentĂ©es). Sans RECURSIVE, les requĂȘtes WITH ne peuvent rĂ©fĂ©rencer d'autres requĂȘtes WITH soƓurs que si elles sont dĂ©clarĂ©es avant dans la liste WITH.

Une propriĂ©tĂ© clĂ© des requĂȘtes WITH est qu'elles ne sont Ă©valuĂ©es qu'une seule fois par exĂ©cution de la requĂȘte principale, mĂȘme si la requĂȘte principale les utilise plus d'une fois. En particulier, vous avez la garantie que les traitements de modification de donnĂ©es sont exĂ©cutĂ©s une seule et unique fois, que la requĂȘte principale lise tout ou partie de leur sortie.

Quand il y a plusieurs requĂȘtes dans la clause WITH, RECURSIVE ne devra ĂȘtre Ă©crit qu'une seule fois, immĂ©diatement aprĂšs WITH. Cela s'applique Ă  toutes les requĂȘtes de la clause WITH, bien que cela n'a pas d'effet sur les requĂȘtes qui n'utilisent pas de rĂ©cursion de rĂ©fĂ©rence en avant (forward references).

Tout se passe comme si la requĂȘte principale et les requĂȘtes WITH Ă©taient toutes exĂ©cutĂ©es en mĂȘme temps. Ceci a pour consĂ©quence que les effets d'un ordre de modification dans une clause WITH ne peuvent pas ĂȘtre vues des autres parties de la requĂȘte, sauf en lisant la sortie de RETURNING. Si deux de ces ordres de modifications tentent de modifier la mĂȘme ligne, les rĂ©sultats sont imprĂ©visibles.

Voir Section 7.8, « RequĂȘtes WITH (Common Table Expressions) Â» pour plus d'informations.

Clause FROM

La clause FROM spécifie une ou plusieurs tables source pour le SELECT. Si plusieurs sources sont spécifiées, le résultat est un produit cartésien (jointure croisée) de toutes les sources. Mais habituellement, des conditions de qualification (via WHERE) sont ajoutées pour restreindre les lignes renvoyées à un petit sous-ensemble du produit cartésien.

La clause FROM peut contenir les Ă©lĂ©ments suivants :

nom_table

Le nom (Ă©ventuellement qualifiĂ© par le nom du schĂ©ma) d'une table ou vue existante. Si ONLY est spĂ©cifiĂ© avant le nom de la table, seule cette table est parcourue. Dans le cas contraire, la table et toutes ses tables filles (s'il y en a) sont parcourues. En option, * peut ĂȘtre ajoutĂ© aprĂšs le nom de la table pour indiquer explicitement que les tables filles sont inclues.

alias

Un nom de substitution pour l'Ă©lĂ©ment FROM contenant l' alias. Un alias est utilisĂ© par briĂšvetĂ© ou pour lever toute ambiguĂŻtĂ© lors d'auto-jointures (la mĂȘme table est parcourue plusieurs fois). Quand un alias est fourni, il cache complĂštement le nom rĂ©el de la table ou fonction ; par exemple, avec FROM truc AS, le reste du SELECT doit faire rĂ©fĂ©rence Ă  cet Ă©lĂ©ment de FROM par f et non pas par truc. Si un alias est donnĂ©, une liste d' alias de colonnes peut aussi ĂȘtre saisi comme noms de substitution pour diffĂ©rentes colonnes de la table.

select

Un sous-SELECT peut apparaĂźtre dans la clause FROM. Il agit comme si sa sortie Ă©tait transformĂ©e en table temporaire pour la durĂ©e de cette seule commande SELECT. Le sous-SELECT doit ĂȘtre entourĂ© de parenthĂšses et un alias doit lui ĂȘtre fourni. Une commande VALUES(7) peut aussi ĂȘtre utilisĂ©e ici.

requĂȘte_with

Une requĂȘte WITH est rĂ©fĂ©rencĂ©e par l'Ă©criture de son nom, exactement comme si le nom de la requĂȘte Ă©tait un nom de table (en fait, la requĂȘte WITH cache toutes les tables qui auraient le mĂȘme nom dans la requĂȘte principale. Si nĂ©cessaire, vous pouvez accĂ©der Ă  une table rĂ©elle du mĂȘme nom en prĂ©cisant le schĂ©ma du nom de la table). Un alias peut ĂȘtre indiquĂ© de la mĂȘme façon que pour une table.

nom_fonction

Des appels de fonctions peuvent apparaĂźtre dans la clause FROM. (Cela est particuliĂšrement utile pour les fonctions renvoyant des ensembles de rĂ©sultats, mais n'importe quelle fonction peut ĂȘtre utilisĂ©e.) Un appel de fonction agit comme si la sortie de la fonction Ă©tait créée comme une table temporaire pour la durĂ©e de cette seule commande SELECT. Quand la clause optionnelle WITH ORDINALITY est ajoutĂ©e Ă  l'appel de la fonction, une nouvelle colonne est ajoutĂ©e aprĂšs toutes les colonnes en sortie de la fonction numĂ©rotant ainsi chaque ligne.

Un alias peut ĂȘtre fourni de la mĂȘme façon pour une table. Si un alias de table est donnĂ©, une liste d'alias de colonnes peut aussi ĂȘtre Ă©crite pour fournir des noms de substitution pour un ou plusieurs attributs du type composite en retour de la fonction, ceci incluant la colonne ajoutĂ©e par ORDINALITY.

Plusieurs appels de fonction peuvent ĂȘtre combinĂ©s en un seul Ă©lĂ©ment dans la clause FROM en les entourant de ROWS FROM( ... ). La sortie d'un tel Ă©lĂ©ment est la concatĂ©nation de la premiĂšre ligne de chaque fonction, puis la deuxiĂšme ligne de chaque fonction, etc. Si certaines fonctions produisent moins de lignes que d'autres, des NULL sont ajoutĂ©es pour les donnĂ©es manquantes, ce qui permet d'avoir comme nombre de lignes celui de la fonction qui en renvoit le plus.

Si la fonction a Ă©tĂ© dĂ©finie comme renvoyant le type de donnĂ©es record, un alias ou le mot clĂ© AS doivent ĂȘtre prĂ©sents, suivi par une liste de dĂ©finition de colonnes de la forme ( nom_colonne type_donnĂ©e [, ... ]). La liste de dĂ©finition des colonnes doit correspondre au nombre rĂ©el et aux types rĂ©els des colonnes renvoyĂ©es par la fonction.

Lors de l'utilisation de la syntaxe ROWS FROM( ... ), si une des fonctions nĂ©cessite une liste de dĂ©finition des colonnes, il est prĂ©fĂ©rable de placer la liste de dĂ©finition des colonnes aprĂšs l'appel de la fonction dans ROWS FROM( ... ). Une liste ded dĂ©finition des colonnes peut ĂȘtre placĂ© aprĂšs la construction ROWS FROM( ... ) seulement s'il n'y a qu'une seule fonction et pas de clause WITH ORDINALITY.

Pour utiliser ORDINALITY avec une liste de définition de colonnes, vous devez utiliser la syntaxe ROWS FROM( ... ) et placer la liste de définition de colonnes dans ROWS FROM( ... ).

type_jointure

Un des éléments

  • [ INNER ] JOIN

  • LEFT [ OUTER ] JOIN

  • RIGHT [ OUTER ] JOIN

  • FULL [ OUTER ] JOIN

  • CROSS JOIN

Pour les types de jointures INNER et OUTER, une condition de jointure doit ĂȘtre spĂ©cifiĂ©e, Ă  choisir parmi NATURAL, ON condition_jointure ou USING (colonne_jointure [, ...]). Voir ci-dessous pour la signification. Pour CROSS JOIN, aucune de ces clauses ne doit apparaĂźtre.

Une clause JOIN combine deux Ă©lĂ©ments FROM, que nous allons appelons « tables Â» par simplicitĂ© bien qu'ils puissent ĂȘtre n'importe quel Ă©lĂ©ment utilisable dans une clause FROM. Les parenthĂšses peuvent ĂȘtre utilisĂ©es pour dĂ©terminer l'ordre d'imbrication. En l'absence de parenthĂšses, les JOIN sont imbriquĂ©s de gauche Ă  droite. Dans tous les cas, JOIN est plus prioritaire que les virgules sĂ©parant les Ă©lĂ©ments FROM.

CROSS JOIN et INNER JOIN produisent un simple produit cartésien. Le résultat est identique à celui obtenu lorsque les deux tables sont listés au premier niveau du FROM, mais restreint par la condition de jointure (si elle existe). CROSS JOIN est équivalent à INNER JOIN ON (TRUE), c'est-à-dire qu'aucune ligne n'est supprimée par qualification. Ces types de jointure sont essentiellement une aide à la notation car ils ne font rien de plus qu'un simple FROM et WHERE.

LEFT OUTER JOIN renvoie toutes les lignes du produit cartésien qualifié (c'est-à-dire toutes les lignes combinées qui satisfont la condition de jointure), plus une copie de chaque ligne de la table de gauche pour laquelle il n'y a pas de ligne à droite qui satisfasse la condition de jointure. La ligne de gauche est étendue à la largeur complÚte de la table jointe par insertion de valeurs NULL pour les colonnes de droite. Seule la condition de la clause JOIN est utilisée pour décider des lignes qui correspondent. Les conditions externes sont appliquées aprÚs coup.

À l'inverse, RIGHT OUTER JOIN renvoie toutes les lignes jointes plus une ligne pour chaque ligne de droite sans correspondance (complĂ©tĂ©e par des NULL pour le cĂŽtĂ© gauche). C'est une simple aide Ă  la notation car il est aisĂ©ment convertible en LEFT en inversant les tables gauche et droite.

FULL OUTER JOIN renvoie toutes les lignes jointes, plus chaque ligne gauche sans correspondance (étendue par des NULL à droite), plus chaque ligne droite sans correspondance (étendue par des NULL à gauche).

ON condition_jointure

condition_jointure est une expression qui retourne une valeur de type boolean (comme une clause WHERE) qui spécifie les lignes d'une jointure devant correspondre.

USING (colonne_jointure [, ...])

Une clause de la forme USING ( a, b, ... ) est un raccourci pour ON table_gauche.a = table_droite.a AND table_gauche.b = table_droite.b .... De plus, USING implique l'affichage d'une seule paire des colonnes correspondantes dans la sortie de la jointure.

NATURAL

NATURAL est un raccourci pour une liste USING qui mentionne toutes les colonnes de mĂȘme nom dans les deux tables. USING qui mentionne toutes les colonnes de mĂȘme nom dans les deux tables. S'il n'y a pas de noms de colonnes communs, NATURAL est Ă©quivalent Ă  ON TRUE.

LATERAL

Le mot clé LATERAL peut précéder un élément sous-SELECT de la clause FROM. Ceci permet au sous-SELECT de faire référence aux colonnes des éléments du FROM qui apparaissent avant lui dans la liste FROM. (Sans LATERAL, chaque sous-SELECT est évalué indépendamment et donc ne peut pas faire référence à tout autre élément de la clause FROM.)

LATERAL peut aussi précéder un élément fonction dans la clause FROM mais dans ce cas, ce n'est pas requis car l'expression de la fonction peut faire référence aux éléments du FROM dans tous les cas.

Un élément LATERAL peut apparaßtre au niveau haut dans la liste FROM ou à l'intérieur d'un arbre JOIN. Dans ce dernier cas, il peut aussi faire référence à tout élément qui se trouvent à la gauche d'un JOIN qui est à sa droite.

Quand un Ă©lĂ©ment du FROM des rĂ©fĂ©rences LATERAL, l'Ă©valuation se fait ainsi : pour chaque ligne d'un Ă©lĂ©ment FROM fournissant une colonne rĂ©fĂ©rencĂ©e ou un ensemble de lignes provenant de plusieurs Ă©lĂ©ments FROM fournissant les colonnes, l'Ă©lĂ©ment LATERAL est Ă©valuĂ©e en utilisant la valeur des colonnes de cette (ou ces) ligne(s). Les lignes rĂ©sultantes sont jointes comme d'habitude avec les lignes pour lesquelles elles ont Ă©tĂ© calculĂ©es. Ceci est rĂ©pĂ©tĂ© pour chaque ligne ou chaque ensemble de lignes provenant de la table contenant les colonnes rĂ©fĂ©rencĂ©es.

Le(s) table(s) contenant les colonnes rĂ©fĂ©rencĂ©es doivent ĂȘtre jointes avec INNER ou LEFT Ă  l'Ă©lĂ©ment LATERAL. Sinon il n'y aurait pas un ensemble bien dĂ©fini de lignes Ă  partir duquel on pourrait construire chaque ensemble de lignes pour l'Ă©lĂ©ment LATERAL. Du coup, bien qu'une construction comme X RIGHT JOIN LATERAL Y est valide syntaxiquement, il n'est pas permis Ă  Y de rĂ©fĂ©rencer X.

Clause WHERE

La clause WHERE optionnelle a la forme générale

WHERE condition
    

oĂč condition est une expression dont le rĂ©sultat est de type boolean. Toute ligne qui ne satisfait pas cette condition est Ă©liminĂ©e de la sortie. Une ligne satisfait la condition si elle retourne vrai quand les valeurs rĂ©elles de la ligne sont substituĂ©es Ă  toute rĂ©fĂ©rence de variable.

Clause GROUP BY

La clause GROUP BY optionnelle a la forme générale

GROUP BY expression [, ...]
    

GROUP BY condense en une seule ligne toutes les lignes sĂ©lectionnĂ©es qui partagent les mĂȘmes valeurs pour les expressions regroupĂ©es. expression peut ĂȘtre le nom d'une colonne en entrĂ©e, le nom ou le numĂ©ro d'une colonne en sortie (Ă©lĂ©ment de la liste SELECT), ou une expression quelconque formĂ©e de valeurs de colonnes en entrĂ©e. En cas d'ambiguĂŻtĂ©, un nom de GROUP BY est interprĂ©tĂ© comme un nom de colonne en entrĂ©e, non en sortie.

Les fonctions d'agrĂ©gat, si utilisĂ©es, sont calculĂ©es pour toutes les lignes composant un groupe, produisant une valeur sĂ©parĂ©e pour chaque groupe. (S'il y a des fonctions d'agrĂ©gat mais pas de clause GROUP BY, la requĂȘte est traitĂ©e comme ayant un seul groupe contenant toutes les lignes sĂ©lectionnĂ©es.) L'ensemble de lignes envoyĂ©es Ă  la fonction d'agrĂ©gat peut ĂȘtre en plus filtrĂ© en ajoutant une clause FILTER lors de l'appel Ă  la fonction d'agrĂ©gat ; voir Section 4.2.7, « Expressions d'agrĂ©gat Â» pour plus d'informations. Quand une clause FILTER est prĂ©sente, seules les lignes correspondant au filtre sont incluses en entrĂ©e de cette fonction d'agrĂ©gat.

Quand GROUP BY est présent ou que des fonctions d'agrégat sont présentes, les expressions du SELECT ne peuvent faire référence qu'à des colonnes groupées, sauf à l'intérieur de fonctions d'agrégat, ou bien si la colonne non groupée dépend fonctionnellement des colonnes groupées. En effet, s'il en était autrement, il y aurait plus d'une valeur possible pour la colonne non groupée. Une dépendance fonctionnelle existe si les colonnes groupées (ou un sous-ensemble de ces derniÚres) sont la clé primaire de la table contenant les colonnes non groupées.

Rappelez-vous que toutes les fonctions d'agrĂ©gat sont Ă©valuĂ©es avant l'Ă©valuation des expressions « scalaires Â» dans la clause HAVING ou la liste SELECT. Ceci signifie que, par exemple, une expression CASE ne peut pas ĂȘtre utilisĂ©e pour ignorer l'Ă©valuation de la fonction d'agrĂ©gat ; voir Section 4.2.14, « RĂšgles d'Ă©valuation des expressions Â».

Actuellement, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE et FOR KEY SHARE ne peuvent pas ĂȘtre spĂ©cifiĂ©es avec GROUP BY.

Clause HAVING

La clause optionnelle HAVING a la forme générale

HAVING condition
    

oĂč condition est identique Ă  celle spĂ©cifiĂ©e pour la clause WHERE.

HAVING Ă©limine les lignes groupĂ©es qui ne satisfont pas Ă  la condition. HAVING est diffĂ©rent de WHERE : WHERE filtre les lignes individuelles avant l'application de GROUP BY alors que HAVING filtre les lignes groupĂ©es créées par GROUP BY. Chaque colonne rĂ©fĂ©rencĂ©e dans condition doit faire rĂ©fĂ©rence sans ambiguĂŻtĂ© Ă  une colonne groupĂ©e, sauf si la rĂ©fĂ©rence apparaĂźt dans une fonction d'agrĂ©gat ou que les colonnes non groupĂ©es sont fonctionnement dĂ©pendantes des colonnes groupĂ©es.

MĂȘme en l'absence de clause GROUP BY, la prĂ©sence de HAVING transforme une requĂȘte en requĂȘte groupĂ©e. Cela correspond au comportement d'une requĂȘte contenant des fonctions d'agrĂ©gats mais pas de clause GROUP BY. Les lignes sĂ©lectionnĂ©es ne forment qu'un groupe, la liste du SELECT et la clause HAVING ne peuvent donc faire rĂ©fĂ©rence qu'Ă  des colonnes Ă  l'intĂ©rieur de fonctions d'agrĂ©gats. Une telle requĂȘte ne produira qu'une seule ligne si la condition HAVING est rĂ©alisĂ©e, aucune dans le cas contraire.

Actuellement, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE et FOR KEY SHARE ne peuvent pas ĂȘtre spĂ©cifiĂ©es avec GROUP BY.

Clause WINDOW

La clause optionnelle WINDOW a la forme générale

WINDOW nom_window AS ( définition_window ) [, ...]
    

oĂč nom_window est un nom qui peut ĂȘtre rĂ©fĂ©rencĂ© par des clauses OVER ou par des dĂ©finitions Window, et dĂ©finition_window est

[ nom_window_existante ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING operateur ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ clause_frame ]
    

Si un nom_window_existante est spĂ©cifiĂ©, il doit se rĂ©fĂ©rer Ă  une entrĂ©e prĂ©cĂ©dente dans la liste WINDOW ; la nouvelle Window copie sa clause de partitionnement de cette entrĂ©e, ainsi que sa clause de tri s'il y en a. Dans ce cas, la nouvelle Window ne peut pas spĂ©cifier sa propre clause PARTITION BY, et ne peut spĂ©cifier de ORDER BY que si la Window copiĂ©e n'en a pas. La nouvelle Window utilise toujours sa propre clause frame ; la Window copiĂ©e ne doit pas possĂ©der de clause frame.

Les Ă©lĂ©ments de la liste PARTITION BY sont interprĂ©tĂ©s Ă  peu prĂšs de la mĂȘme façon que des Ă©lĂ©ments de la section intitulĂ©e « Clause GROUP BY Â», sauf qu'ils sont toujours des expressions simples et jamais le nom ou le numĂ©ro d'une colonne en sortie. Une autre diffĂ©rence est que ces expressions peuvent contenir des appels Ă  des fonctions d' agrĂ©gat, ce qui n'est pas autorisĂ© dans une clause GROUP BY classique. Ceci est autorisĂ© ici parce que le windowing se produit aprĂšs le regroupement et l' agrĂ©gation.

De façon similaire, les Ă©lĂ©ments de la liste ORDER BY sont interprĂ©tĂ©s Ă  peu prĂšs de la mĂȘme façon que les Ă©lĂ©ments d'un la section intitulĂ©e « Clause ORDER BY Â», sauf que les expressions sont toujours prises comme de simples expressions et jamais comme le nom ou le numĂ©ro d'une colonne en sortie.

La clause clause_frame optionnelle dĂ©finit la frame window pour les fonctions window qui dĂ©pendent de la frame (ce n'est pas le cas de toutes). La frame window est un ensemble de lignes liĂ©es Ă  chaque ligne de la requĂȘte (appelĂ©e la ligne courante). La clause_frame peut ĂȘtre une des clauses suivantes :

{ RANGE | ROWS } début_portée
{ RANGE | ROWS } BETWEEN début_portée AND fin_portée
    

oĂč dĂ©but_frame et fin_frame peuvent valoir

UNBOUNDED PRECEDING
valeur PRECEDING
CURRENT ROW
valeur FOLLOWING
UNBOUNDED FOLLOWING
    

Si fin_frame n'est pas prĂ©cisĂ©, il vaut par dĂ©faut CURRENT ROW. Les restrictions sont les suivantes : dĂ©but_frame ne peut pas valoir UNBOUNDED FOLLOWING, fin_frame ne peut pas valoir UNBOUNDED PRECEDING, et le choix fin_frame ne peut apparaĂźtre avant le choix dĂ©but_frame -- par exemple RANGE BETWEEN CURRENT ROW AND valeur PRECEDING n'est pas permis.

L'option par dĂ©faut pour la clause frame est RANGE UNBOUNDED PRECEDING, ce qui revient au mĂȘme que RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ; il positionne la frame pour qu'il couvre toutes les lignes Ă  partir du dĂ©but de la partition jusqu'Ă  la derniĂšre ligne Ă  Ă©galitĂ© avec la ligne courante (une ligne que la clause ORDER BY considĂšre Ă©quivalente Ă  la ligne actuelle ou Ă  toutes les lignes s'il n'y a pas de clause ORDER BY). GĂ©nĂ©ralement, UNBOUNDED PRECEDING signifie que la frame commence Ă  la premiĂšre ligne de la partition, et de mĂȘme UNBOUNDED FOLLOWING signifie que la frame se termine avec la derniĂšre ligne de la partition (quel que soit le mode, RANGE ou bien ROWS ). Dans le mode ROWS, CURRENT ROW signifie que la frame commence ou se termine sur la ligne courante  ; mais dans le mode RANGE cela signifie que la frame dĂ©bute ou se termine sur la premiĂšre ou la derniĂšre des lignes Ă  Ă©galitĂ© avec la ligne courante dans l'ordre de la clause ORDER BY. Les valeur PRECEDING et valeur FOLLOWING sont actuellement seulement permis en mode ROWS. Ils indiquent que la frame dĂ©bute ou se termine autant de lignes avant ou aprĂšs la ligne courante. valeur doit ĂȘtre une expression entiĂšre, ne contenant aucune variable, fonction d' agrĂ©gat ni fonction window. La valeur ne doit ĂȘtre ni null ni nĂ©gative  ; mais elle peut ĂȘtre de zĂ©ro, ce qui sĂ©lectionne la ligne courante elle-mĂȘme.

Attention, les options ROWS peuvent produire des rĂ©sultats imprĂ©visibles si l'ordre dĂ©fini par l' ORDER BY n'ordonne pas les lignes de maniĂšre unique. Les options RANGE sont conçues pour s'assurer que les lignes qui sont Ă  Ă©galitĂ© suivant l'ordre de l' ORDER BY sont traitĂ©es de la mĂȘme maniĂšre  ; toutes les lignes Ă  Ă©galitĂ© seront ensemble dans la frame ou ensemble hors de la frame.

L'utilitĂ© d'une clause WINDOW est de spĂ©cifier le comportement des fonctions window apparaissant dans la clause la section intitulĂ©e « Liste SELECT Â» ou la clause la section intitulĂ©e « Clause ORDER BY Â» de la requĂȘte. Ces fonctions peuvent rĂ©fĂ©rencer les entrĂ©es de clauses WINDOW par nom dans leurs clauses OVER. Toutefois, il n'est pas obligatoire qu'une entrĂ©e de clause WINDOW soit rĂ©fĂ©rencĂ©e quelque part ; si elle n'est pas utilisĂ©e dans la requĂȘte, elle est simplement ignorĂ©e. Il est possible d'utiliser des fonctions window sans aucune clause WINDOW puisqu'une fonction window peut spĂ©cifier sa propre dĂ©finition de window directement dans sa clause OVER. Toutefois, la clause WINDOW Ă©conomise de la saisie quand la mĂȘme dĂ©finition window est utilisĂ©e pour plus d'une fonction window.

Actuellement, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE et FOR KEY SHARE ne peuvent pas ĂȘtre spĂ©cifiĂ©es avec GROUP BY.

Les fonctions window sont dĂ©crites en dĂ©tail dans Section 3.5, « Fonctions de fenĂȘtrage Â», Section 4.2.8, « Appels de fonction de fenĂȘtrage Â» et Section 7.2.4, « Traitement de fonctions Window Â».

Liste SELECT

La liste SELECT (entre les mots clés SELECT et FROM) spécifie les expressions qui forment les lignes en sortie de l'instruction SELECT. Il se peut que les expressions fassent référence aux colonnes traitées dans la clause FROM. En fait, en général, elles le font.

Comme pour une table, chaque colonne de sortie d'un SELECT a un nom. Dans un SELECT simple, ce nom est juste utilisĂ© pour donner un titre Ă  la colonne pour l'affichage, mais quand le SELECT est une sous-requĂȘte d'une requĂȘte plus grande, le nom est vu par la grande requĂȘte comme le nom de colonne de la table virtuelle produite par la sous-requĂȘte. Pour indiquer le nom Ă  utiliser pour une colonne de sortie, Ă©crivez AS nom_de_sortie aprĂšs l'expression de la colonne. (Vous pouvez omettre AS seulement si le nom de colonne souhaitĂ© n'est pas un mot clĂ© rĂ©servĂ© par PostgreSQLℱ (voir Annexe C, Mots-clĂ© SQL). Pour vous protĂ©ger contre l'ajout futur d'un mot clĂ©, il est recommandĂ© que vous Ă©criviez toujours AS ou que vous mettiez le nom de sortie entre guillemets. Si vous n'indiquez pas de nom de colonne, un nom est choisi automatiquement par PostgreSQLℱ. Si l'expression de la colonne est une simple rĂ©fĂ©rence Ă  une colonne alors le nom choisi est le mĂȘme que le nom de la colonne. Dans les cas plus complexes, un nom de fonction ou de type peut ĂȘtre utilisĂ©, ou le systĂšme peut opter pour un nom gĂ©nĂ©rĂ© automatiquement tel que ?column?.

Un nom de colonne de sortie peut ĂȘtre utilisĂ© pour se rĂ©fĂ©rer Ă  la valeur de la colonne dans les clauses ORDER BY et GROUP BY, mais pas dans la clauseWHERE ou HAVING ; Ă  cet endroit, vous devez Ă©crire l'expression.

* peut ĂȘtre utilisĂ©, Ă  la place d'une expression, dans la liste de sortie comme raccourci pour toutes les colonnes des lignes sĂ©lectionnĂ©es. De plus, nom_table.* peut ĂȘtre Ă©crit comme raccourci pour toutes les colonnes de cette table. Dans ces cas, il est impossible de spĂ©cifier de nouveaux noms avec AS ; les noms des colonnes de sorties seront les mĂȘme que ceux de la table.

DISTINCT Clause

Si SELECT DISTINCT est spécifié, toutes les lignes en double sont supprimées de l'ensemble de résultats (une ligne est conservée pour chaque groupe de doublons). SELECT ALL spécifie le contraire : toutes les lignes sont conservées. C'est l'option par défaut.

SELECT DISTINCT ON ( expression [, ...] ) conserve seulement la premiĂšre ligne de chaque ensemble de lignes pour lesquelles le rĂ©sultat de l'expression est identique. Les expressions DISTINCT ON expressions sont interprĂ©tĂ©es avec les mĂȘmes rĂšgles que pour ORDER BY (voir ci-dessous). Notez que la « premiĂšre ligne Â» de chaque ensemble est imprĂ©visible, Ă  moins que la clause ORDER BY ne soit utilisĂ©e, assurant ainsi que la ligne souhaitĂ©e apparaisse en premier. Par exemple :

SELECT DISTINCT ON (lieu) lieu, heure, rapport
    FROM rapport_météo
    ORDER BY lieu, heure DESC;
    

renvoie le rapport météo le plus récent de chaque endroit. Mais si nous n'avions pas utilisé ORDER BY afin de forcer le tri du temps dans le sens descendant des temps pour chaque endroit, nous aurions récupéré, pour chaque lieu, n'importe quel bulletin de ce lieu.

La (ou les ) expression(s) DISTINCT ON doivent correspondre à l'expression (ou aux expressions) ORDER BY la(les) plus à gauche. La clause ORDER BY contient habituellement des expressions supplémentaires qui déterminent l'ordre des lignes au sein de chaque groupe DISTINCT ON.

Actuellement, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE et FOR KEY SHARE ne peuvent pas ĂȘtre spĂ©cifiĂ©es avec DISTINCT.

Clause UNION

La clause UNION a la forme gĂ©nĂ©rale :

instruction_select UNION [ ALL | DISTINCT ] instruction_select
    

instruction_select est une instruction SELECT sans clause ORDER BY, LIMIT, FOR SHARE ou FOR UPDATE. (ORDER BY et LIMIT peuvent ĂȘtre attachĂ©s Ă  une sous-expression si elle est entourĂ©e de parenthĂšses. Sans parenthĂšses, ces clauses s'appliquent au rĂ©sultat de l'UNION, non Ă  l'expression Ă  sa droite.)

L'opĂ©rateur UNION calcule l'union ensembliste des lignes renvoyĂ©es par les instructions SELECT impliquĂ©es. Une ligne est dans l'union de deux ensembles de rĂ©sultats si elle apparaĂźt dans au moins un des ensembles. Les deux instructions SELECT qui reprĂ©sentent les opĂ©randes directes de l'UNION doivent produire le mĂȘme nombre de colonnes et les colonnes correspondantes doivent ĂȘtre d'un type de donnĂ©es compatible.

Sauf lorsque l'option ALL est spĂ©cifiĂ©e, il n'y a pas de doublons dans le rĂ©sultat de UNION. ALL empĂȘche l'Ă©limination des lignes dupliquĂ©es. UNION ALL est donc significativement plus rapide qu'UNION, et sera prĂ©fĂ©rĂ©. DISTINCT peut Ă©ventuellement ĂȘtre ajoutĂ© pour prĂ©ciser explicitement le comportement par dĂ©faut : l'Ă©limination des lignes en double.

Si une instruction SELECT contient plusieurs opérateurs UNION, ils sont évalués de gauche à droite, sauf si l'utilisation de parenthÚses impose un comportement différent.

Actuellement, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE et FOR KEY SHARE ne peuvent pas ĂȘtre spĂ©cifiĂ©s pour un rĂ©sultat d'UNION ou pour toute entrĂ©e d'un UNION.

Clause INTERSECT

La clause INTERSECT a la forme gĂ©nĂ©rale :

instruction_select INTERSECT [ ALL | DISTINCT ] instruction_select
    

instruction_select est une instruction SELECT sans clause ORDER BY, LIMIT, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE ou FOR KEY SHARE.

L'opérateur INTERSECT calcule l'intersection des lignes renvoyées par les instructions SELECT impliquées. Une ligne est dans l'intersection des deux ensembles de résultats si elle apparaßt dans chacun des deux ensembles.

Le rĂ©sultat d'INTERSECT ne contient aucune ligne dupliquĂ©e sauf si l'option ALL est spĂ©cifiĂ©e. Dans ce cas, une ligne dupliquĂ©e m fois dans la table gauche et n fois dans la table droite apparaĂźt min(m,n) fois dans l'ensemble de rĂ©sultats. DISTINCT peut Ă©ventuellement ĂȘtre ajoutĂ© pour prĂ©ciser explicitement le comportement par dĂ©faut : l'Ă©limination des lignes en double.

Si une instruction SELECT contient plusieurs opérateurs INTERSECT, ils sont évalués de gauche à droite, sauf si l'utilisation de parenthÚses impose un comportement différent. INTERSECT a une priorité supérieur à celle d'UNION. C'est-à-dire que A UNION B INTERSECT C est lu comme A UNION (B INTERSECT C).

Actuellement, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE et FOR KEY SHARE ne peuvent pas ĂȘtre spĂ©cifiĂ©s pour un rĂ©sultat d'INTERSECT ou pour une entrĂ©e d'INTERSECT.

Clause EXCEPT

La clause EXCEPT a la forme gĂ©nĂ©rale :

instruction_select EXCEPT [ ALL | DISTINCT ] instruction_select
    

instruction_select est une instruction SELECT sans clause ORDER BY, LIMIT, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE ou FOR KEY SHARE.

L'opérateur EXCEPT calcule l'ensemble de lignes qui appartiennent au résultat de l'instruction SELECT de gauche mais pas à celui de droite.

Le rĂ©sultat d'EXCEPT ne contient aucune ligne dupliquĂ©e sauf si l'option ALL est spĂ©cifiĂ©e. Dans ce cas, une ligne dupliquĂ©e m fois dans la table gauche et n fois dans la table droite apparaĂźt max(m-n,0) fois dans l'ensemble de rĂ©sultats. DISTINCT peut Ă©ventuellement ĂȘtre ajoutĂ© pour prĂ©ciser explicitement le comportement par dĂ©faut : l'Ă©limination des lignes en double.

Si une instruction SELECT contient plusieurs opĂ©rateurs EXCEPT, ils sont Ă©valuĂ©s de gauche Ă  droite, sauf si l'utilisation de parenthĂšses impose un comportement diffĂ©rent. EXCEPT a la mĂȘme prioritĂ© qu'UNION.

Actuellement, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE et FOR KEY SHARE ne peuvent pas ĂȘtre spĂ©cifiĂ©s dans un rĂ©sultat EXCEPT ou pour une entrĂ©e d'un EXCEPT.

Clause ORDER BY

La clause optionnelle ORDER BY a la forme gĂ©nĂ©rale :

ORDER BY expression [ ASC | DESC | USING opérateur ] [ NULLS { FIRST | LAST } ] [, ...]
    

La clause ORDER BY impose le tri des lignes de résultat suivant les expressions spécifiées. Si deux lignes sont identiques suivant l'expression la plus à gauche, elles sont comparées avec l'expression suivante et ainsi de suite. Si elles sont identiques pour toutes les expressions de tri, elles sont renvoyées dans un ordre dépendant de l'implantation.

Chaque expression peut ĂȘtre le nom ou le numĂ©ro ordinal d'une colonne en sortie (Ă©lĂ©ment de la liste SELECT). Elle peut aussi ĂȘtre une expression arbitraire formĂ©e Ă  partir de valeurs des colonnes.

Le numéro ordinal fait référence à la position ordinale (de gauche à droite) de la colonne de résultat. Cette fonctionnalité permet de définir un ordre sur la base d'une colonne dont le nom n'est pas unique. Ce n'est pas particuliÚrement nécessaire parce qu'il est toujours possible d'affecter un nom à une colonne de résultat avec la clause AS.

Il est aussi possible d'utiliser des expressions quelconques dans la clause ORDER BY, ce qui inclut des colonnes qui n'apparaissent pas dans la liste rĂ©sultat du SELECT. Ainsi, l'instruction suivante est valide :

SELECT nom FROM distributeurs ORDER BY code;
    

Il y a toutefois une limitation à cette fonctionnalité. La clause ORDER BY qui s'applique au résultat d'une clause UNION, INTERSECT ou EXCEPT ne peut spécifier qu'un nom ou numéro de colonne en sortie, pas une expression.

Si une expression ORDER BY est un nom qui correspond Ă  la fois Ă  celui d'une colonne rĂ©sultat et Ă  celui d'une colonne en entrĂ©e, ORDER BY l'interprĂšte comme le nom de la colonne rĂ©sultat. Ce comportement est Ă  l'opposĂ© de celui de GROUP BY dans la mĂȘme situation. Cette incohĂ©rence est imposĂ©e par la compatibilitĂ© avec le standard SQL.

Un mot clĂ© ASC (ascendant) ou DESC (descendant) peut ĂȘtre ajoutĂ© aprĂšs toute expression de la clause ORDER BY. ASC est la valeur utilisĂ©e par dĂ©faut. Un nom d'opĂ©rateur d'ordre spĂ©cifique peut Ă©galement ĂȘtre fourni dans la clause USING. Un opĂ©rateur de tri doit ĂȘtre un membre plus-petit-que ou plus-grand-que de certaines familles d'opĂ©rateur B-tree. ASC est habituellement Ă©quivalent Ă  USING < et DESC Ă  USING >. Le crĂ©ateur d'un type de donnĂ©es utilisateur peut dĂ©finir Ă  sa guise le tri par dĂ©faut qui peut alors correspondre Ă  des opĂ©rateurs de nom diffĂ©rent.

Si NULLS LAST est indiquĂ©, les valeurs NULL sont listĂ©es aprĂšs toutes les valeurs non NULL  si NULLS FIRST est indiquĂ©, les valeurs NULL apparaissent avant toutes les valeurs non NULL. Si aucune des deux n'est prĂ©sente, le comportement par dĂ©faut est NULLS LAST quand ASC est utilisĂ© (de façon explicite ou non) et NULLS FIRST quand DESC est utilisĂ© (donc la valeur par dĂ©faut est d'agir comme si les NULL Ă©taient plus grands que les non NULL). Quand USING est indiquĂ©, le tri des NULL par dĂ©faut dĂ©pend du fait que l'opĂ©rateur est un plus-petit-que ou un plus-grand-que.

Notez que les options de tri s'appliquent seulement Ă  l'expression qu'elles suivent. Par exemple, ORDER BY x, y DESC ne signifie pas la mĂȘme chose que ORDER BY x DESC, y DESC.

Les chaĂźnes de caractĂšres sont triĂ©es suivant le collationnement qui s'applique Ă  la colonne triĂ©e. Ce collationnement est surchargeable si nĂ©cessaire en ajoutant une clause COLLATE dans l'expression, par exemple ORDER BY mycolumn COLLATE "en_US". Pour plus d'informations, voir Section 4.2.10, « Expressions de collationnement Â» et Section 22.2, « Support des collations Â».

Clause LIMIT

La clause LIMIT est constituĂ©e de deux sous-clauses indĂ©pendantes :

LIMIT { nombre | ALL }
OFFSET début
    

nombre spécifie le nombre maximum de lignes à renvoyer alors que début spécifie le nombre de lignes à passer avant de commencer à renvoyer des lignes. Lorsque les deux clauses sont spécifiées, début lignes sont passées avant de commencer à compter les nombre lignes à renvoyer.

Si l'expression de compte est évaluée à NULL, il est traité comme LIMIT ALL, c'est-à-dire sans limite. Si début est évalué à NULL, il est traité comme OFFSET 0.

SQL:2008 a introduit une sytaxe diffĂ©rente pour obtenir le mĂȘme rĂ©sultat. PostgreSQLℱ supporte aussi cette syntaxe.

OFFSET début { ROW | ROWS }
FETCH { FIRST | NEXT } [ compte ] { ROW | ROWS } ONLY
    

Avec cette syntaxe, la valeur de start et de count doit ĂȘtre une constante, un paramĂštre ou un nom de variable d'aprĂšs la norme ; PostgreSQL Ă©tend ça Ă  toute expression mais il sera gĂ©nĂ©ralement nĂ©cessaire de l'entourer de parenthĂšses pour Ă©viter toute ambiguĂŻtĂ©. Si compte est omis dans une clause FETCH, il vaut 1 par dĂ©faut. ROW et ROWS ainsi que FIRST et NEXT sont des mots qui n'influencent pas les effets de ces clauses. D'aprĂšs le standard, la clause OFFSET doit venir avant la clause FETCH si les deux sont prĂ©sentes ; PostgreSQLℱ est plus laxiste et autorise un ordre diffĂ©rent.

Avec LIMIT, utiliser la clause ORDER BY permet de contraindre l'ordre des lignes de résultat. Dans le cas contraire, le sous-ensemble obtenu n'est pas prévisible -- rien ne permet de savoir à quel ordre correspondent les lignes retournées. Celui-ci ne sera pas connu tant qu'ORDER BY n'aura pas été précisé.

Lors de la gĂ©nĂ©ration d'un plan de requĂȘte, le planificateur tient compte de LIMIT. Le risque est donc grand d'obtenir des plans qui diffĂšrent (ordres des lignes diffĂ©rents) suivant les valeurs utilisĂ©es pour LIMIT et OFFSET. Ainsi, sĂ©lectionner des sous-ensembles diffĂ©rents d'un rĂ©sultat Ă  partir de valeurs diffĂ©rentes de LIMIT/OFFSET aboutit Ă  des rĂ©sultats incohĂ©rents Ă  moins d'avoir figĂ© l'ordre des lignes Ă  l'aide de la clause ORDER BY. Ce n'est pas un bogue, mais une consĂ©quence du fait que SQL n'assure pas l'ordre de prĂ©sentation des rĂ©sultats sans utilisation d'une clause ORDER BY.

Il est mĂȘme possible pour des exĂ©cutions rĂ©pĂ©tĂ©es de la mĂȘme requĂȘte LIMIT de renvoyer diffĂ©rents sous-ensembles des lignes d'une table s'il n'y a pas de clause ORDER BY pour forcer la sĂ©lection d'un sous-ensemble dĂ©terministe. Encore une fois, ce n'est pas un bogue ; le dĂ©terminisme des rĂ©sultats n'est tout simplement pas garanti dans un tel cas.

Clause de verrouillage

FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE et FOR KEY SHARE sont des clauses de verrouillage. Elles affectent la façon dont SELECT verrouille les lignes au moment de leur obtention sur la table.

La clause de verrouillage a la forme suivante :

FOR force_verrou [ OF nom_table [, ...] ] [ NOWAIT ]
    

oĂč force_verrou fait partie de :

UPDATE
NO KEY UPDATE
SHARE
KEY SHARE
    

Pour plus d'informations sur chaque mode de verrouillage au niveau ligne, voir Section 13.3.2, « Verrous au niveau ligne Â».

Pour Ă©viter Ă  l'opĂ©ration d'attendre la validation des autres transactions, on utilise l'option NOWAIT. SELECT FOR UPDATE NOWAIT rapporte une erreur si une ligne sĂ©lectionnĂ©e ne peut pas ĂȘtre verrouillĂ©e immĂ©diatement. Il n'y a pas d'attente. NOWAIT s'applique seulement au(x) verrou(x) niveau ligne -- le verrou niveau table ROW SHARE est toujours pris de façon ordinaire (voir Chapitre 13, ContrĂŽle d'accĂšs simultanĂ©). L'option NOWAIT de LOCK(7) peut toujours ĂȘtre utilisĂ©e pour acquĂ©rir le verrou niveau table sans attendre.

Si des tables particuliĂšres sont nommĂ©es dans une clause de verrouillage, alors seules les lignes provenant de ces tables sont verrouillĂ©es ; toute autre table utilisĂ©e dans le SELECT est simplement lue. Une clause de verrouillage sans liste de tables affecte toutes les tables utilisĂ©es dans l'instruction. Si une clause de verrouillage est appliquĂ©e Ă  une vue ou Ă  une sous-requĂȘte, cela affecte toutes les tables utilisĂ©es dans la vue ou la sous-requĂȘte. NĂ©anmoins, ces clauses ne s'appliquent pas aux requĂȘtes WITH rĂ©fĂ©rencĂ©es par la clĂ© primaire. Si vous voulez qu'un verrouillage de lignes intervienne dans une requĂȘte WITH, spĂ©cifiez une clause de verrouillage Ă  l'intĂ©rieur de la requĂȘte WITH.

Plusieurs clauses de verrouillage peuvent ĂȘtre donnĂ©es si il est nĂ©cessaire de spĂ©cifier diffĂ©rents comportements de verrouillage pour diffĂ©rentes tables. Si la mĂȘme table est mentionnĂ© (ou affectĂ©e implicitement) par plus d'une clause de verrouillage, alors elle est traitĂ©e comme la clause la plus forte. De façon similaire, une table est traitĂ©e avec NOWAIT si c'est spĂ©cifiĂ©e sur au moins une des clauses qui l'affectent.

Les clauses de verrouillage nĂ©cessitent que chaque ligne retournĂ©e soit clairement identifiable par une ligne individuelle d'une table ; ces options ne peuvent, par exemple, pas ĂȘtre utilisĂ©es avec des fonctions d'agrĂ©gats.

Quand une clause de verrouillage apparaissent au niveau le plus Ă©levĂ© d'une requĂȘte SELECT, les lignes verrouillĂ©es sont exactement celles qui sont renvoyĂ©es par la requĂȘte ; dans le cas d'une requĂȘte avec jointure, les lignes verrouillĂ©es sont celles qui contribuent aux lignes jointes renvoyĂ©es. De plus, les lignes qui ont satisfait aux conditions de la requĂȘte au moment de la prise de son instantanĂ© sont verrouillĂ©es, bien qu'elles ne seront pas retournĂ©es si elles ont Ă©tĂ© modifiĂ©es aprĂšs la prise du snapshot et ne satisfont plus les conditions de la requĂȘte. Si LIMIT est utilisĂ©, le verrouillage cesse une fois que suffisamment de lignes ont Ă©tĂ© renvoyĂ©es pour satisfaire la limite (mais notez que les lignes ignorĂ©es Ă  cause de la clause OFFSET seront verrouillĂ©es). De la mĂȘme maniĂšre, si une clause de verrouillage est utilisĂ© pour la requĂȘte d'un curseur, seules les lignes rĂ©ellement rĂ©cupĂ©rĂ©es ou parcourues par le curseur seront verrouillĂ©es.

Si une clause de verrouillage apparait dans un sous-SELECT, les lignes verrouillĂ©es sont celles renvoyĂ©es par la sous-requĂȘte Ă  la requĂȘte externe. Cela peut concerner moins de lignes que l'Ă©tude de la sous-requĂȘte seule pourrait faire penser, parce que les conditions de la requĂȘte externe peuvent ĂȘtre utilisĂ©es pour optimiser l'exĂ©cution de la sous-requĂȘte. Par exemple,

SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss WHERE col1 = 5;
    

verrouillera uniquement le lignes pour lesquelles col1 = 5, mĂȘme si cette condition n'est pas Ă©crite dans la sous-requĂȘte.

Les anciennes versions Ă©chouaient Ă  prĂ©server un verrou qui est mis Ă  jour par un point de sauvegarde ultĂ©rieur. Par exemple, ce code :

BEGIN;
SELECT * FROM ma_table WHERE cle = 1 FOR UPDATE;
SAVEPOINT s;
UPDATE ma_table SET ... WHERE cle = 1;
ROLLBACK TO s;
    

va échouer à conserver le verrou FOR UPDATE aprÚs la commande ROLLBACK TO. Ceci a été corrigé en 9.3.

[Attention]

Attention

Il est possible qu'une commande SELECT exĂ©cutĂ©e au niveau d'isolation READ COMMITTED et utilisant ORDER BY et une clause de verrouillage renvoie les lignes dans le dĂ©sordre. C'est possible car l' ORDER BY est appliquĂ© en premier. La commande trie le rĂ©sultat, mais peut alors ĂȘtre bloquĂ©e le temps d'obtenir un verrou sur une ou plusieurs des lignes. Une fois que le SELECT est dĂ©bloquĂ©, des valeurs sur la colonne qui sert Ă  ordonner peuvent avoir Ă©tĂ© modifiĂ©es, ce qui entraĂźne ces lignes apparaissant dans le dĂ©sordre (bien qu'elles soient dans l'ordre par rapport aux valeurs d'origine de ces colonnes). Ceci peut ĂȘtre contournĂ© si besoin en plaçant la clause FOR UPDATE/SHARE dans une sous-requĂȘte, par exemple

SELECT * FROM (SELECT * FROM matable FOR UPDATE) ss ORDER BY column1;
     

Notez que cela entraßne le verrouillage de toutes les lignes de matable, alors que FOR UPDATE au niveau supérieur verrouillerait seulement les lignes réellement renvoyées. Cela peut causer une différence de performance significative, en particulier si l' ORDER BY est combiné avec LIMIT ou d'autres restrictions. Cette technique est donc recommandée uniquement si vous vous attendez à des mises à jour concurrentes sur les colonnes servant à l'ordonnancement et qu'un résultat strictement ordonné est requis.

Au niveau d'isolation de transactions REPEATABLE READ et SERIALIZABLE, cela causera une erreur de sérialisation (avec un SQLSTATE valant '40001'), donc il n'est pas possible de recevoir des lignes non triées avec ces niveaux d'isolation.

Commande TABLE

La commande

TABLE nom
    

est équivalente à

SELECT * FROM nom
    

Elle peut ĂȘtre utilisĂ©e comme commande principale d'une requĂȘte, ou bien comme une variante syntaxique permettant de gagner de la place dans des parties de requĂȘtes complexes. Seuls les clauses de verrou de WITH, UNION, INTERSECT, EXCEPT, ORDER BY, LIMIT, OFFSET, FETCH et FOR peuvent ĂȘtre utilisĂ©es avec TABLE ; la clause WHERE et toute forme d'agrĂ©gation ne peuvent pas ĂȘtre utilisĂ©es.

Exemples

Joindre la table films avec la table distributeurs :

SELECT f.titre, f.did, d.nom, f.date_prod, f.genre
    FROM distributeurs d, films f
    WHERE f.did = d.did

       titre       | did |     nom      | date_prod  |   genre
-------------------+-----+--------------+------------+------------
 The Third Man     | 101 | British Lion | 1949-12-23 | Drame
 The African Queen | 101 | British Lion | 1951-08-11 | Romantique
 ...
   

Additionner la colonne longueur de tous les films, grouper les rĂ©sultats par genre :

SELECT genre, sum(longueur) AS total FROM films GROUP BY genre;

   genre    | total
------------+-------
 Action     | 07:34
 Comédie    | 02:58
 Drame      | 14:28
 Musical    | 06:42
 Romantique | 04:38
   

Additionner la colonne longueur de tous les films, grouper les rĂ©sultats par genre et afficher les groupes dont les totaux font moins de cinq heures :

SELECT genre, sum(longueur) AS total
    FROM films
    GROUP BY genre
    HAVING sum(longueur) < interval '5 hours';

   genre    | total
------------+-------
 Comedie    | 02:58
 Romantique | 04:38
   

Les deux exemples suivants reprĂ©sentent des façons identiques de trier les rĂ©sultats individuels en fonction du contenu de la deuxiĂšme colonne (nom) :

SELECT * FROM distributeurs ORDER BY nom;
SELECT * FROM distributeurs ORDER BY 2;

 did |       nom
-----+------------------
 109 | 20th Century Fox
 110 | Bavaria Atelier
 101 | British Lion
 107 | Columbia
 102 | Jean Luc Godard
 113 | Luso films
 104 | Mosfilm
 103 | Paramount
 106 | Toho
 105 | United Artists
 111 | Walt Disney
 112 | Warner Bros.
 108 | Westward
   

L'exemple suivant présente l'union des tables distributeurs et acteurs, restreignant les résultats à ceux de chaque table dont la premiÚre lettre est un W. Le mot clé ALL est omis, ce qui permet de n'afficher que les lignes distinctes.

distributeurs:               acteurs:
 did |     nom               id |     nom
-----+--------------        ----+----------------
 108 | Westward               1 | Woody Allen
 111 | Walt Disney            2 | Warren Beatty
 112 | Warner Bros.           3 | Walter Matthau
 ...                         ...

SELECT distributeurs.nom
    FROM distributeurs
    WHERE distributeurs.nom LIKE 'W%'
UNION
SELECT actors.nom
    FROM acteurs
    WHERE acteurs.nom LIKE 'W%';

      nom
----------------
 Walt Disney
 Walter Matthau
 Warner Bros.
 Warren Beatty
 Westward
 Woody Allen
   

L'exemple suivant prĂ©sente l'utilisation d'une fonction dans la clause FROM, avec et sans liste de dĂ©finition de colonnes :

CREATE FUNCTION distributeurs(int) RETURNS SETOF distributeurs AS $$
    SELECT * FROM distributeurs WHERE did = $1;
$$ LANGUAGE SQL;

SELECT * FROM distributeurs(111);
 did |    name
-----+-------------
 111 | Walt Disney

CREATE FUNCTION distributeurs_2(int) RETURNS SETOF record AS $$
    SELECT * FROM distributeurs WHERE did = $1;
$$ LANGUAGE SQL;

SELECT * FROM distributeurs_2(111) AS (f1 int, f2 text);
 f1  |     f2
-----+-------------
 111 | Walt Disney
   

Voici un exemple d'une fonction avec la colonne ordinality :

SELECT * FROM unnest(ARRAY['a','b','c','d','e','f']) WITH ORDINALITY;
 unnest | ordinality
--------+----------
 a      |        1
 b      |        2
 c      |        3
 d      |        4
 e      |        5
 f      |        6
(6 rows)
   

Cet exemple montre comment utiliser une clause WITH simple:

WITH t AS (
    SELECT random() as x FROM generate_series(1, 3)
  )
SELECT * FROM t
UNION ALL
SELECT * FROM t

         x
--------------------
  0.534150459803641
  0.520092216785997
 0.0735620250925422
  0.534150459803641
  0.520092216785997
 0.0735620250925422
   

Notez que la requĂȘte WITH n'a Ă©tĂ© Ă©valuĂ©e qu'une seule fois, ce qui fait qu'on a deux jeux contenant les mĂȘmes trois valeurs.

Cet exemple utilise WITH RECURSIVE pour trouver tous les subordonnĂ©s (directs ou indirects) de l'employĂ©e Marie, et leur niveau de subordination, Ă  partir d'une table qui ne donne que les subordonnĂ©s directs :

WITH RECURSIVE recursion_employes(distance, nom_employe, nom_manager) AS (
    SELECT 1, nom_employe, nom_manager
    FROM employe
    WHERE nom_manager = 'Marie'
  UNION ALL
    SELECT er.distance + 1, e.nom_employe, e.nom_manager
    FROM recursion_employes er, employe e
    WHERE er.nom_employe = e.nom_manager
  )
SELECT distance, nom_employe FROM recursion_employes;
   

Notez la forme typique des requĂȘtes rĂ©cursives : une condition initiale, suivie par UNION, suivis par la partie rĂ©cursive de la requĂȘte. Assurez-vous que la partie rĂ©cursive de la requĂȘte finira par ne plus retourner d'enregistrement, sinon la requĂȘte bouclera indĂ©finiment (Voir Section 7.8, « RequĂȘtes WITH (Common Table Expressions) Â» pour plus d'exemples).

Cet exemple utilise LATERAL pour appliquer une fonction renvoyant des lignes, recupere_nom_produits(), pour chaque ligne de la table manufacturiers :

SELECT m.nom AS mnom, pnom
FROM manufacturiers m, LATERAL recupere_nom_produits(m.id) pnom;
   

Les manufacturiers qui n'ont pas encore de produits n'apparaĂźtront pas dans le rĂ©sultat car la jointure est interne. Si vous voulons inclure les noms de ces manufacturiers, la requĂȘte doit ĂȘtre Ă©crite ainsi :

SELECT m.name AS mnom, pnom
FROM manufacturiers m LEFT JOIN LATERAL recupere_nom_produits(m.id) pnom ON true;
   

Compatibilité

L'instruction SELECT est évidemment compatible avec le standard SQL. Mais il y a des extensions et quelques fonctionnalités manquantes.

Clauses FROM omises

PostgreSQLℱ autorise l'omission de la clause FROM. Cela permet par exemple de calculer le rĂ©sultat d'expressions simples :

SELECT 2+2;

 ?column?
----------
        4
    

D'autres bases de données SQL interdisent ce comportement, sauf à introduire une table virtuelle d'une seule ligne sur laquelle exécuter la commande SELECT.

S'il n'y a pas de clause FROM, la requĂȘte ne peut pas rĂ©fĂ©rencer les tables de la base de donnĂ©es. La requĂȘte suivante est, ainsi, invalide :

SELECT distributors.* WHERE distributors.name = 'Westward';
    

Les versions antĂ©rieures Ă  PostgreSQLℱ 8.1 acceptaient les requĂȘtes de cette forme en ajoutant une entrĂ©e implicite Ă  la clause FROM pour chaque table rĂ©fĂ©rencĂ©e. Ce n'est plus autorisĂ©.

Listes SELECT vides

La liste des expressions en sortie aprĂšs SELECT peut ĂȘtre vide, produisant ainsi une table de rĂ©sultats Ă  zĂ©ro colonne. Ceci n'est pas une syntaxe valide suivant le standard SQL. PostgreSQLℱ l'autorise pour ĂȘtre cohĂ©rent avec le fait qu'il accepte des tables Ă  zĂ©ro colonne. NĂ©anmoins, une liste vide n'est pas autorisĂ© quand un DISTINCT est utilisĂ©.

Omettre le mot clé AS

Dans le standard SQL, le mot clĂ© AS peut ĂȘtre omis devant une colonne de sortie Ă  partir du moment oĂč le nouveau nom de colonne est un nom valide de colonne (c'est-Ă -dire, diffĂ©rent d'un mot clĂ© rĂ©servĂ©). PostgreSQLℱ est lĂ©gĂšrement plus restrictif : AS est nĂ©cessaire si le nouveau nom de colonne est un mot clĂ© quel qu'il soit, rĂ©servĂ© ou non. Il est recommandĂ© d'utiliser AS ou des colonnes de sortie entourĂ©es de guillemets, pour Ă©viter tout risque de conflit en cas d'ajout futur de mot clĂ©.

Dans les Ă©lĂ©ments de FROM, le standard et PostgreSQLℱ permettent que AS soit omis avant un alias qui n'est pas un mot clĂ© rĂ©servĂ©. Mais c'est peu pratique pour les noms de colonnes, Ă  causes d'ambiguĂŻtĂ©s syntaxiques.

ONLY et l'héritage

Le standard SQL impose des parenthĂšses autour du nom de table aprĂšs la clause ONLY, comme dans SELECT * FROM ONLY (tab1), ONLY (tab2) WHERE .... PostgreSQLℱ considĂšre les parenthĂšses comme Ă©tant optionnelles.

PostgreSQLℱ autorise une * en fin pour indiquer explicitement le comportement opposĂ© de la clause ONLY (donc inclure les tables filles). Le standard ne le permet pas.

(Ces points s'appliquent de la mĂȘme façon Ă  toutes les commandes SQL supportant l'option ONLY.)

Appels de fonction dans la clause FROM

PostgreSQLℱ autorise un appel de fonction dans la liste FROM. Pour le standard SQL, il serait nĂ©cessaire de placer cet appel de fonction dans un sous-SELECT ; autrement dit, la syntaxe FROM fonc(...) alias est Ă  peu prĂšs Ă©quivalente Ă  FROM LATERAL (SELECT fonc(...)) alias. Notez que LATERAL est considĂ©rĂ© comme Ă©tant implicite ; ceci est dĂ» au fait que le standard rĂ©clame la sĂ©mantique de LATERAL pour un Ă©lĂ©ment UNNEST() dans la clause FROM. PostgreSQLℱ traite UNNEST() de la mĂȘme façon que les autres fonctions renvoyant des lignes.

Espace logique disponible pour GROUP BY et ORDER BY

Dans le standard SQL-92, une clause ORDER BY ne peut utiliser que les noms ou numĂ©ros des colonnes en sortie, une clause GROUP BY que des expressions fondĂ©es sur les noms de colonnes en entrĂ©e. PostgreSQLℱ va plus loin, puisqu'il autorise chacune de ces clauses Ă  utiliser Ă©galement l'autre possibilitĂ©. En cas d'ambiguĂŻtĂ©, c'est l'interprĂ©tation du standard qui prĂ©vaut. PostgreSQLℱ autorise aussi l'utilisation d'expressions quelconques dans les deux clauses. Les noms apparaissant dans ces expressions sont toujours considĂ©rĂ©s comme nom de colonne en entrĂ©e, pas en tant que nom de colonne du rĂ©sultat.

SQL:1999 et suivant utilisent une dĂ©finition lĂ©gĂšrement diffĂ©rente, pas totalement compatible avec le SQL-92. NĂ©anmoins, dans la plupart des cas, PostgreSQLℱ interprĂšte une expression ORDER BY ou GROUP BY en suivant la norme SQL:1999.

Dépendances fonctionnelles

PostgreSQLℱ reconnaĂźt les dĂ©pendances fonctionnelles (qui permettent que les nom des colonnes ne soient pas dans le GROUP BY) seulement lorsqu'une clĂ© primaire est prĂ©sente dans la liste du GROUP BY. Le standard SQL spĂ©cifie des configurations supplĂ©mentaires qui doivent ĂȘtre reconnues.

Restrictions sur la clause WINDOW

Le standard SQL fournit des options additionnelles pour la clause_frame des window. PostgreSQLℱ ne supporte Ă  ce jour que les options mentionnĂ©es prĂ©cĂ©demment.

LIMIT et OFFSET

Les clauses LIMIT et OFFSET sont une syntaxe spĂ©cifique Ă  PostgreSQLℱ, aussi utilisĂ©e dans MySQLℱ. La norme SQL:2008 a introduit les clauses OFFSET ... FETCH {FIRST|NEXT}... pour la mĂȘme fonctionnalitĂ©, comme montrĂ© plus haut dans la section intitulĂ©e « Clause LIMIT Â». Cette syntaxe est aussi utilisĂ©e par IBM DB2ℱ. (Les applications Ă©crites pour Oracleℱ contournent frĂ©quemment le problĂšme par l'utilisation de la colonne auto-gĂ©nĂ©rĂ©e rownum pour obtenir les effets de ces clauses, qui n'est pas disponible sous PostgreSQL,)

FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE, FOR KEY SHARE

Bien que FOR UPDATE soit prĂ©sent dans le standard SQL, le standard ne l'autorise que comme une option de DECLARE CURSOR. PostgreSQLℱ l'autorise dans toute requĂȘte SELECT et dans toute sous-requĂȘte SELECT, mais c'est une extension. Les variantes FOR NO KEY UPDATE, FOR SHARE et FOR KEY SHARE, ainsi que l'option NOWAIT, n'apparaissent pas dans le standard.

Ordre de modification de données dans un WITH

PostgreSQLℱ permet que les clauses INSERT, UPDATE, et DELETE soient utilisĂ©es comme requĂȘtes WITH. Ceci n'est pas prĂ©sent dans le standard SQL.

Clauses non standard

La clause DISTINCT ON est une extension du standard SQL.

ROWS FROM( ... ) est une extension du standard SQL.