Vous êtes libres de redistribuer et/ou modifier cette création selon les conditions suivantes :
Paternité
Pas d'utilisation commerciale
Partage des conditions initiales à l'identique
Commentaire sur le reste de la ligne
-- commentaire
Commentaire dans un bloc
/* bloc
*/
SELECT
SELECT expressions_colonnes
[ FROM elements_from ]
[ WHERE predicats ]
[ ORDER BY expressions_orderby ]
[ LIMIT limite ]
[ OFFSET offset ];
référence de colonne :
table.colonne
AS
:
expression AS alias
DISTINCT
SELECT DISTINCT expressions_colonnes...
+
, -
, /
, *
||
now()
age(timestamp)
extract( 'year' FROM timestamp)
date_part('Y',timestamp)
char_length(chaine)
count(*)
FROM expression_table [, expression_table ...]
AS
optionnel :
reference_table alias
la table sera ensuite référencée par l'alias
reference_table [AS] alias
reference_table AS alias (alias_colonne1, ...)
Nom_Objet
devient nom_objet
"
conserve la casse
"Nom_Objet"
=
, <
, >
, =<
, >=
, <>
NOT
expression operateur_comparaison expression
predicat OR predicat
predicat AND predicat
Comparaison de motif
chaine LIKE motif ESCAPE 'c'
%
: toute chaine de 0 à plusieurs caractères
_
: un seul caractèreExpression régulière POSIX
chaine ~ motif
Liste de valeurs
expression IN (valeur1 [, ...])
Chevauchement d'intervalle de valeurs
expression BETWEEN expression AND expression
Chevauchement d'intervalle de dates
(date1, date2) OVERLAPS (date3, date4)
Tris des lignes selon des expressions
ORDER BY expression [ ASC | DESC | USING opérateur ]
[ NULLS { FIRST | LAST } ] [, ...]
ASC
ou DESC
NULL
: NULLS FIRST
ou NULLS LAST
COLLATE collation
OFFSET n
FETCH {FIRST | NEXT} n ROWS ONLY
LIMIT n
OFFSET
doit apparaitre avant FETCH
FROM
,
char
, varchar
integer
, smallint
, bigint
real
, double precision
numeric
, decimal
boolean
date
, time
timestamp
interval
bit
, bit varying
XML
char(n)
varchar(n)
'
'chaîne de caractères'
E
ou e
E'chaîne de caractères'
U&
U&'chaîne de caractères'
smallint
, integer
, bigint
real
, double precision
numeric(precision, echelle)
, decimal(precision, echelle)
.
e
[+-]chiffres]e
[+-]chiffres]e
[+-]chiffresTYPE 'chaine'
boolean
TRUE
FALSE
NULL
(ie valeur absente)date
time
timestamp
interval
TYPE 'chaine'
'YYYY-MM-DD HH24:MI:SS.ssssss'
'YYYY-MM-DD HH24:MI:SS.ssssss+fuseau'
'YYYY-MM-DD HH24:MI:SS.ssssss' AT TIME ZONE 'fuseau'
INTERVAL 'durée interval'
timezone
SET TIME ZONE
'Europe/Paris'
'CEST'
'+02'
bit(n)
, bit varying(n)
B
B'01010101'
X
X'55'
xml
serial
smallserial
bigserial
IDENTITY
text
bytea
array
enum
cidr
, inet
, macaddr
uuid
json
jsonb
hstore
range
enum
)range
)tableau
CREATE TYPE
SELECT
N'hésitez pas, c'est le moment !
Data Definition Language
)Data Manipulation Language
)Transaction Control Language
)Data Definition Language
CREATE
CREATE SCHEMA s1;
ALTER
renommage
ALTER type_objet ancien_nom RENAME TO nouveau_nom ;
changement de propriétaire
ALTER type_objet nom_objet OWNER TO proprietaire ;
changement de schéma
ALTER type_objet nom_objet SET SCHEMA nom_schema ;
DROP
supprimer un objet :
DROP type_objet nom_objet ;
supprimer un objet et ses dépendances :
DROP type_objet nom_objet CASCADE ;
public
CREATE SCHEMA nom_schéma
ALTER SCHEMA nom_schéma
DROP SCHEMA [ IF EXISTS ] nom_schéma [ CASCADE ]
nom_schema
.nom_objet
search_path
SET search_path = schema1,schema2,public;
$user, public
MINVALUE
MAXVALUE
START
INCREMENT
CACHE
CYCLE
CREATE SEQUENCE nom [ INCREMENT incrément ]
[ MINVALUE valeurmin | NO MINVALUE ]
[ MAXVALUE valeurmax | NO MAXVALUE ]
[ START [ WITH ] début ]
[ CACHE cache ]
[ [ NO ] CYCLE ]
[ OWNED BY { nom_table.nom_colonne | NONE } ]
ALTER SEQUENCE nom [ INCREMENT increment ]
[ MINVALUE valeurmin | NO MINVALUE ]
[ MAXVALUE valeurmax | NO MAXVALUE ]
[ START [ WITH ] début ]
[ RESTART [ [ WITH ] nouveau_début ] ]
[ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { nom_table.nom_colonne | NONE } ]
DROP SEQUENCE nom [, ...]
nextval('nom_sequence')
currval('nom_sequence')
nextval()
doit être appelé avant dans la même sessionserial
/bigserial
/smallserial
nextval(...)
IDENTITY
CREATE TABLE
CREATE TABLE nom_table (
definition_colonnes
definition_contraintes
) clause_stockage;
nom_colonne type [ COLLATE collation ] [ contrainte ]
[, ...]
DEFAULT
CREATE TABLE ... (LIKE table clause_inclusion)
INCLUDING DEFAULTS
INCLUDING CONSTRAINTS
INCLUDING INDEXES
ALTER TABLE
Supprimer une table :
DROP TABLE nom_table;
Supprimer une table et tous les objets dépendants :
DROP TABLE nom_table CASCADE;
Construction :
[CONSTRAINT nom_contrainte]
PRIMARY KEY ( nom_colonne [, ... ] )
NULL
UNIQUE
UNIQUE
!= index UNIQUE
Construction :
[ CONSTRAINT nom_contrainte]
{ UNIQUE ( nom_colonne [, ... ] )
UNIQUE
et NOT NULL
FOREIGN KEY
[ CONSTRAINT nom_contrainte ] FOREIGN KEY ( nom_colonne [, ...] )
REFERENCES table_reference [ (colonne_reference [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE action ] [ ON UPDATE action ] }
MATCH
MATCH FULL
(complète)MATCH SIMPLE
(partielle)GENERATED ... AS IDENTITY
ALWAYS
BY DEFAULT
serial
ON UPDATE
ON DELETE
NOT NULL
CHECK
DEFERRABLE
, NOT DEFERRABLE
INITIALLY DEFERED
, INITIALLY IMMEDIATE
SELECT
peut lire les données d'une table ou plusieurs tables
INSERT
UPDATE
DELETE
SELECT
INSERT INTO nom_table [ ( nom_colonne [, ...] ) ]
{ liste_valeurs | requete }
INSERT INTO nom_table [ ( nom_colonne [, ...] ) ]
VALUES ( { expression | DEFAULT } [, ...] ) [, ...]
INSERT INTO nom_table [ ( nom_colonne [, ...] ) ]
requête
UPDATE
UPDATE nom_table
SET
{
nom_colonne = { expression | DEFAULT }
|
( nom_colonne [, ...] ) = ( { expression | DEFAULT } [, ...] )
} [, ...]
[ FROM liste_from ]
[ WHERE condition | WHERE CURRENT OF nom_curseur ]
DELETE FROM nom_table [ [ AS ] alias ]
[ WHERE condition
INSERT
, UPDATE
ou DELETE
requete_sql RETURNING ( * | expression )
BEGIN TRANSACTION
COMMIT
ROLLBACK
SAVEPOINT nom_savepoint
RELEASE SAVEPOINT nom_savepoint
ROLLBACK TO SAVEPOINT nom_savepoint
CREATE
, ALTER
, DROP
INSERT
, UPDATE
, DELETE
N'hésitez pas, c'est le moment !
NULL
GROUP BY
, HAVING
CASE
UNION
, EXCEPT
, INTERSECT
NULL
NULL
:
NULL
telle qu'elle est implémentée dans SQL peut poser plus de problèmes qu'elle n'en résout. Son comportement est parfois étrange et est source de nombreuses erreurs et de confusions.NULL
le plus possible
NULL
correctement lorsqu'il le fautNULL
pour INSERT
et UPDATE
INSERT
NULL
NOT NULL
NULL
NULL
est inapplicable
NULL
WHERE
:
IS NULL
ou IS NOT NULL
AND
:
false
si NULL AND false
NULL
si NULL AND true
ou NULL AND NULL
OR
:
true
si NULL OR true
NULL
si NULL OR false
ou NULL OR NULL
NULL
count(*)
NULL
par une autre valeur
COALESCE(attribut, ...);
Regroupement de données :
GROUP BY expression [, ...]
NULL
si l'ensemble est vide
count()
Comptage :
count(expression)
count(*)
count(colonne)
Valeur minimale :
min(expression)
Valeur maximale :
max(expression)
Moyenne :
avg(expression)
Somme :
sum(expression)
Écart-type :
stddev(expression)
Variance :
variance(expression)
HAVING
WHERE
s'applique sur les lignes luesHAVING
s'applique sur les lignes groupées(
et )
SELECT
WHERE
HAVING
IN
ANY
ALL
expression IN (sous-requete)
IN
vaut true
IN
vaut false
NULL
IN
vaut NULL
NULL
NULL
expression NOT IN (sous-requete)
NOT IN
vaut true
NULL
NOT IN
vaut false
NOT IN
vaut NULL
NULL
NULL
expression operateur ANY (sous-requete)
NULL
expression operateur ALL (sous-requete)
NULL
FROM
EXISTS (sous-requete)
EXISTS
vérifie la présence ou l'absence de résultats
CROSS JOIN
INNER JOIN
Condition de jointure par prédicats :
table1 [INNER] JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
table1 [INNER] JOIN table2 USING (colonne [, ...])
Liste des colonnes implicites :
table1 NATURAL [INNER] JOIN table2
NULL
NULL
NULL
NULL
Condition de jointure par prédicats :
table1 LEFT [OUTER] JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
table1 LEFT [OUTER] JOIN table2 USING (colonne [, ...])
Liste des colonnes implicites :
table1 NATURAL LEFT [OUTER] JOIN table2
Condition de jointure par prédicats :
table1 RIGHT [OUTER] JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
table1 RIGHT [OUTER] JOIN table2 USING (colonne [, ...])
Liste des colonnes implicites :
table1 NATURAL RIGHT [OUTER] JOIN table2
Condition de jointure par prédicats :
table1 FULL OUTER JOIN table2 ON prédicat [...]
Condition de jointure implicite par liste des colonnes impliquées :
table1 FULL OUTER JOIN table2 USING (colonne [, ...])
Liste des colonnes implicites :
table1 NATURAL FULL OUTER JOIN table2
switch
en C ou JavaCASE expression
WHEN valeur THEN expression
WHEN valeur THEN expression
(...)
ELSE expression
END
CASE WHEN expression THEN expression
WHEN expression THEN expression
(...)
ELSE expression
END
CASE
à l'intérieur d'autres expressions CASE
ELSE
UNION
INTERSECT
EXCEPT
Regroupement avec dédoublonnage :
requete_select1 UNION requete_select2
Regroupement sans dédoublonnage :
requete_select1 UNION ALL requete_select2
Intersection de deux ensembles avec dédoublonnage :
requete_select1 INTERSECT requete_select2
Intersection de deux ensembles sans dédoublonnage :
requete_select1 INTERSECT ALL requete_select2
Différence entre deux ensembles avec dédoublonnage :
requete_select1 EXCEPT requete_select2
Différence entre deux ensembles sans dédoublonnage :
requete_select1 EXCEPT ALL requete_select2
N'hésitez pas, c'est le moment !
CAST (expression AS type)
expression::type
chaîne1 || chaîne2
char_length(chaîne)
lower(chaîne)
upper(chaîne)
substring(chaîne [from int] [for int])
position(sous-chaîne in chaîne)
+
-
*
/
%
Arrondi : round(numeric)
Troncature : trunc(numeric [, precision])
Entier le plus petit : floor(numeric)
Entier le plus grand : ceil(numeric)
Générer une suite d'entiers : generate_series(borne_debut, borne_fin, intervalle)
Générer un nombre aléatoire : random()
current_date
current_time
current_timestamp
age(timestamp)
age(timestamp, timestamp)
date_trunc(text, timestamp)
date_trunc('month' from date_naissance)
extract(text, timestamp)
extract('year' from date_naissance)
timestamp
, time
ou date
date/time - date/time = interval
date/time + time = date/time
date/time + interval = date/time
interval
interval * numeric = interval
interval / numeric = interval
interval + interval = interval
to_char(timestamp, text)
to_char(current_timestamp, 'DD/MM/YYYY HH24:MI:SS')
to_date(text, text)
to_date('05/12/2000', 'DD/MM/YYYY')
to_timestamp(text, text)
to_timestamp('05/12/2000 12:00:00', 'DD/MM/YYYY HH24:MI:SS')
datestyle
generate_series(timestamp_debut, timestamp_fin, intervalle)
CREATE VIEW vue (colonne ...) AS SELECT ...
SELECT * FROM vue;
GRANT
et REVOKE
security_barrier
INSTEAD OF
PREPARE
, préparation du plan d'exécution d'une requêteEXECUTE
, passage des paramètres de la requête et exécution réelleCREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ]
ON table_name
( { column_name | ( expression ) }
[ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
[ TABLESPACE tablespace_name ]
[ WHERE predicate ]
SELECT * FROM taches WHERE fait IS false ORDER BY date_rendu;
CREATE INDEX ON taches(date_rendu) WHERE fait IS false;
SELECT * FROM employes WHERE upper(nom)='DUPONT';
CREATE INDEX ON employes(upper(nom));
identifiant, nom_attribut, valeur
hstore
, jsonb
)float
ou double
numeric(x, y)
pour les calculs précis (financiers notamment)NULL
LIKE
Le problème est similaire à tout autre langage :
LIKE
N'hésitez pas, c'est le moment !
WHERE
Cette requête d'exemple :
SELECT matricule, nom, prenom, nom_service, fonction, localisation
FROM employes emp
JOIN services ser ON (emp.num_service = ser.num_service)
WHERE ser.localisation = 'Nantes';
L'objet de ce module est de comprendre son plan d'exécution :
Hash Join (cost=1.06..2.29 rows=4 width=48)
Hash Cond: (emp.num_service = ser.num_service)
-> Seq Scan on employes emp (cost=0.00..1.14 rows=14 width=35)
-> Hash (cost=1.05..1.05 rows=1 width=21)
-> Seq Scan on services ser (cost=0.00..1.05 rows=1 width=21)
Filter: ((localisation)::text = 'Nantes'::text)
pg_class
relpages
et reltuples
NULL
)pg_statistic
pg_stats
pg_class
relpages
et reltuples
CREATE STATISTICS
default_statistics_target = 100
Configurable par colonne
ALTER TABLE nom ALTER [ COLUMN ] colonne SET STATISTICS valeur;
300 * default_statistics_target
EXISTS
, IN
et certaines jointures externes :
PostgreSQL dispose de la parallélisation depuis la version 9.6. Cela ne concernait que les jointures de type Nested Loop et Hash Join. Quant au Merge Join, il a fallu attendre la version 10 pour que la parallélisation soit supportée.
SELECT * FROM t1 WHERE c1=1 AND c2=1
c1=1
est vrai pour 20% des lignesc2=1
est vrai pour 10% des lignesCREATE STATISTICS
pour des statistiques multi-colonnesSELECT *
FROM commandes
WHERE extract('year' from date_commande) = 2014;
extract
SELECT * FROM t1 WHERE c2 LIKE 'x%';
Delete (actual time=111.251..111.251 rows=0 loops=1)
-> Hash Join (actual time=1.094..21.402 rows=9347 loops=1)
-> Seq Scan on lot_a30_descr_lot
(actual time=0.007..11.248 rows=34934 loops=1)
-> Hash (actual time=0.501..0.501 rows=561 loops=1)
-> Bitmap Heap Scan on lot_a10_pdl
(actual time=0.121..0.326 rows=561 loops=1)
Recheck Cond: (id_fantoir_commune = 320013)
-> Bitmap Index Scan on...
(actual time=0.101..0.101 rows=561 loops=1)
Index Cond: (id_fantoir_commune = 320013)
Trigger for constraint fk_lotlocal_lota30descrlot:
time=1010.358 calls=9347
Trigger for constraint fk_nonbatia21descrsuf_lota30descrlot:
time=2311695.025 calls=9347
Total runtime: 2312835.032 ms
SELECT DISTINCT t1.* FROM t1 JOIN t2 ON (t1.id=t2.t1_id);
DISTINCT
est souvent utilisé pour dédoublonner les lignes de t1
GROUP BY
est plus rapideGROUP BY
Prédicat incluant une transformation :
WHERE col1 + 2 > 5
Opérateur non-supporté par l'index :
WHERE col1 <> 'valeur';
effective_cache_size
NOT IN
avec une sous-requête
NOT EXISTS
UNION
au lieu de UNION ALL
SELECT
LATERAL
N'hésitez pas, c'est le moment !
SELECT c1 FROM t1 WHERE c1<10
SELECT pg_class.relname, pg_class.reltuples
FROM pg_class
LEFT JOIN pg_namespace
ON pg_class.relnamespace=pg_namespace.oid;