Académique Documents
Professionnel Documents
Culture Documents
SQL Hacks
Tips & Tools for Digging into Your Data
Andrew Cumming & Gordon Russel
O’Reilly Hacks Series
Fabien Coelho
1 2
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
3 4
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
1 juillet 1 janvier
SELECT 1 AS jour, mois.nom AS mois
1 août VALUES (1, ’janvier’), (2, ’février’), 2 février
FROM (VALUES
(’juillet’), (’août’), (’septembre’), 1 septembre (3, ’mars’), (4, ’avril’), 3 mars
(’octobre’), (’novembre’), (’décembre’), (5, ’mai’), (6, ’juin’); 4 avril
1 octobre
(’...’)) 5 mai
1 novembre
AS mois(nom);
1 décembre 6 juin
1 ...
5 6
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
7 8
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
7 128
9 10
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
Exemple UPSERT
id name
Données initiales 1 Calvin
MERGE/UPSERT : INSERT ou UPDATE
2 hbs
1 Calvin
Données finales
2 Hobbes
3 Susie
11 12
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
13 14
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
Extraction sur une hiérarchie de tables — applique une aggrégations sur certains tuples seulement
pid nom — syntaxe : AGG(...) FILTER(WHERE ...)
1 Mum
-- nombre de films avant et après 1950
2 Dad
SELECT * FROM Identité; SELECT
3 Calvin
COUNT(*) FILTER(WHERE année < 1950) AS "avant",
4 Hobbes
COUNT(*) FILTER(WHERE année >= 1950) AS "après",
5 Rosalyn
COUNT(*) AS "total"
pid nom promo
FROM films;
SELECT * FROM Élève; 3 Calvin 4th
5 6 11
15 16
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
— équivalent à UNION, valeurs non gardées remplacées par NULL ); Suisse Allemand 5.2
17 18
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
Néerlandais 23.9
FROM PaysLanguePopulation Néerlandais 23.9
-- dernier groupe
252.6 252.6
ORDER BY pays, langue;
19 20
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
21 22
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
— numérotation selon un tri, une partition, les deux. . . RANK() OVER (ORDER BY val DESC) 2 15 2
FROM Notes 3 17 1
— syntaxe : fonctions et clauses
ORDER BY id;
4 13 4
fonctions d’aggrégation COUNT SUM. . . 5 15 2
23 24
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
25 26
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
27 28
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
— associe tous les précédents à chaque opération SELECT id, quand, montant, description,
— complexité en n2 . . . plus ou moins inutilisable SUM(montant) OVER (ORDER BY id ASC)
— préférer une solution applicative ? FROM CompteCheque;
id quand montant description sum
-- jointure speciale...
1 2005-02-01 00:00:00 1000.00 versement initial 1000.00
SELECT cc.id, cc.quand, cc.montant, cc.description,
2 2005-05-09 00:00:00 -100.00 tirage 900.00
SUM(run.montant)
3 2005-05-11 00:00:00 -450.00 sous-tirage 450.00
FROM CompteCheque AS cc
4 2006-01-01 00:00:00 200.00 ouf 650.00
JOIN CompteCheque AS run ON run.id<=cc.id
5 2006-12-23 00:00:00 -700.00 joyeux noel -50.00
GROUP BY cc.id, cc.quand, cc.montant, cc.description
6 2007-02-28 00:00:00 123.45 des sous ! 73.45
ORDER BY cc.id ASC;
29 30
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
ORDER BY yr ASC; 1986 8.1 8.1 — attention, barrière d’optimisation : implémentation matérialisée
1987 8.3 8.1 WITH RECURSIVE calcul itératif. . .
1988 7.8 7.9
— calcul fermeture transitive : arrêt quand ajout vide
1989 7.6 7.7
31 32
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
WHERE moy < (SELECT AVG(moy) FROM auteur moy) parent TEXT NOT NULL, Mum Grand Pa
degre INTEGER NOT NULL,
ORDER BY auteur; Mum Granny
PRIMARY KEY(enfant,parent)
auteur moy );
Allen 01:42:00
Ozu 01:37:00
33 34
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
35 36
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
WITH avec INSERT UPDATE DELETE Plus longues séquences de températures croissantes
WITH archived AS (
http://tapoueh.org/blog/2018/02/find-the-number-of-the-longest-continuously-rising-days-for-a-stock/
DELETE FROM Invoice
WHERE paid AND sent < CURRENT DATE - INTERVAL ’1 month’ date temp
RETURNING * 2017-01-01 -0.5
)
2017-01-02 1.3
INSERT INTO Archive — variations journalières
2017-01-03 1.1
SELECT * FROM archived;
LAG(c, 1) OVER (ORDER BY d) 2017-01-04 1.4
— longueur des séquences croissantes 2017-01-05 2.4
WITH changed AS (
UPDATE stuff WITH RECURSIVE 2017-01-06 1.1
37 38
Fabien Coelho SQL bien avancé Fabien Coelho SQL bien avancé
WITH RECURSIVE
Delta AS ( -- day-on-day temperature delta
SELECT LAG(date, 1) OVER (ORDER BY date) AS dstart,
PostgreSQL/SQL Turing complet : oui !
date AS dend,
temp - LAG(temp, 1) OVER (ORDER BY date) AS inc http://blog.coelho.net/tags.html#Turing-ref
FROM Temperature),
RaisingTemp AS ( -- increasing temperature sequences — bande semi infinie de symboles, position, état
SELECT dstart, dend, 1 AS cnt
— transitions : nouvel état, symbole et position
FROM Delta
WHERE inc >= 0
UNION boucle . . .
SELECT p.dstart, d.dend, p.cnt + 1 — WITH RECURSIVE pour itérer
FROM RaisingTemp AS p
JOIN Delta AS d ON (p.dend = d.dstart) — MAX OVER pour retrouver le symbole suivant
WHERE d.inc >= 0) — CROSS JOIN pour agrandir la bande
-- keep longest sequences found
SELECT dstart, MAX(cnt) AS cnt récursion avec une fonction SQL
FROM RaisingTemp
GROUP BY dstart
ORDER BY cnt DESC, dstart ASC LIMIT 5;
39 40
Fabien Coelho SQL bien avancé
List of Slides
9 Tableau constant...
41