Views

2025-09-04 07:37:37 +02:00
parent 3cd635cd18
commit 0747417319
6 changed files with 184 additions and 31 deletions

@@ -3,6 +3,7 @@
- [Fonctions d'agrégation](aggregation.md) - [Fonctions d'agrégation](aggregation.md)
- [Jointure](Jointures.md) - [Jointure](Jointures.md)
- [Sous requêtes](sousrequete.md) - [Sous requêtes](sousrequete.md)
- [Vues et fonctions](View.md)
- [Fonctions de fenêtrage](window.md) - [Fonctions de fenêtrage](window.md)
- [Données spatiales](Spatial.md) - [Données spatiales](Spatial.md)
- [Arbres](Arbres.md) - [Arbres](Arbres.md)

@@ -104,11 +104,14 @@ WHERE gauche IS NULL;
Lister les articles dont la famille n'existe pas. Lister les articles dont la famille n'existe pas.
```sql ```sql
select a.* from article a select * from article
left join famille f on f.code = a.famille_code left join famille on famille.code = article.famille_code
where f.code is null where famille.code is null
``` ```
Attention ! La valeur `null` ne peut être comparée à rien. L'égalité avec null retourne ni vrai ni faux mais null. Ainsi null n'est pas égal à null. Pour la comparaison avec null il faut utiliser les mots-clés `is` ou `is not`.
## Jointure croisée ou produit cartésien ## Jointure croisée ou produit cartésien
La jointure croisée renvoie le produit cartésien des deux tables. Chaque ligne de la première table est combinée avec chaque ligne de la deuxième table. Cela produit un très grand nombre de lignes de résultat. La jointure croisée renvoie le produit cartésien des deux tables. Chaque ligne de la première table est combinée avec chaque ligne de la deuxième table. Cela produit un très grand nombre de lignes de résultat.
@@ -197,17 +200,19 @@ Avantages :
```sql ```sql
select a.* from article a select * from article
where not exists (select 1 from famille where a.famille_code = famille.code) where not exists (
select 1 from famille
where a.famille_code = famille.code
)
``` ```
```sql ```sql
SELECT g.* select * from article
FROM gauche g where famille_code not in (
WHERE g.id NOT IN ( select code from famille
SELECT d.g_id where code = article.famille_code
FROM droite d )
);
``` ```
Cette requête est elle aussi équivalente cependant il existe un risque de mauvaise interprétation. Si le sous-select contient au moins un NULL, alors toutes les lignes sont rejetées (car la comparaison avec la valeur NULL dans id NOT IN ( …, NULL, … ) est indéterminée.) Cette requête est elle aussi équivalente cependant il existe un risque de mauvaise interprétation. Si le sous-select contient au moins un NULL, alors toutes les lignes sont rejetées (car la comparaison avec la valeur NULL dans id NOT IN ( …, NULL, … ) est indéterminée.)
@@ -241,5 +246,3 @@ join adherent b on a.nom = b.nom
and a.naissance = b.naissance and a.naissance = b.naissance
and a.id <> b.id and a.id <> b.id
``` ```
## Lateral

75
View.md Normal file

@@ -0,0 +1,75 @@
# Les vues
> Une vue est une requête SQL enregistrée dans la base de données et exposée **comme une table virtuelle**.
Elle nenregistre pas physiquement les données, mais seulement **la définition** de la requête.
```sql
create view ticket_complet as
select t.id, t.adherent_id, t.date_ticket,
t.mode_rglt, round(sum(prix_unitaire * quantite),2) as montant
from ticket t
join ligne l on l.ticket_id = t.id
group by t.id
```
# Les vues matérialisées
> Une vue matérialisée est semblable à une vue, mais elle stocke physiquement sur le disque le résultat de la requête.
Cela améliore les performances pour des calculs lourds mais nécessite une actualisation quand les données sources changent.
```sql
create materialized view ticket_completZ as
select t.id, t.adherent_id, t.date_ticket,
t.mode_rglt, round(sum(prix_unitaire * quantite),2) as montant
from ticket t
join ligne l on l.ticket_id = t.id
group by t.id
```
Actualisation des données de la vue matérialisée.
```sql
REFRESH MATERIALIZED VIEW ticket_completZ;
```
Comme sur les tables il est possible de créer des index sur les colonnes des vues matérialisées pour accélerer encore les tris.
# les fonctions
> Une fonction stockée est un bloc de code SQL (ou éventuellement un autre langage de programmation) qui retourne une valeur.
On lutilise pour encapsuler une logique métier.
Les caractères `$$` delimitent le bloc de code. Ils permetent de savoir où commence le code de la fonction et où il s'arrête.
## Les fonctions scalaires
C'est le cas le plus simple : la fonction retourne une seule valeur (comme un nombre, du texte, une date, un booléen, etc.).
## Les fonctions table
```sql
create or replace function f_dernier_ticket(adherent_id_param int)
returns table (id int, adherent_id int,
date_ticket timestamp, mode_rglt int,
montant numeric, n int)
as $$
select * from (
select *,
row_number() OVER ( order by tc.date_ticket desc ) as n
from ticket_completz tc
where adherent_id = adherent_id_param
) where n = 1
$$ language sql;
```
## Les fonctions
## Les procédures stockées
les procédures stockées sont proches des fonctions mais :
- Elles ne retournent pas de valeur directement.
- Elles peuvent exécuter des transactions (COMMIT, ROLLBACK).
- Elles servent à automatiser des traitements plus larges et plus complexes (chargements de données, batchs).

@@ -12,19 +12,21 @@ select count(*) from adherent;
On peut compter sur n'importe quelle colonne, dans ce cas, pour ne pas avoir à choisir on utilise le caractère joker *. On peut compter sur n'importe quelle colonne, dans ce cas, pour ne pas avoir à choisir on utilise le caractère joker *.
En ajoutant le mot clé `distinct` l'opération s'effectue sur les valeurs uniques d'une ou de plusieurs colonnes. En ajoutant le mot clé `distinct` l'opération s'effectue sur les **valeurs uniques** d'une ou de plusieurs colonnes.
```sql ```sql
select count(distinct codepostal) from adherent; select count(distinct codepostal) from adherent;
``` ```
Attention ! `count(codepostal)` compte toute les lignes, soit le nombre total d'ahérent.
#### Filtre #### Filtre
Il est également possible d'ajouter une condition `where` à cette colonne uniquement. Cest souvent plus lisible et performant que de faire un CASE WHEN imbriqué. Il est également possible d'ajouter une condition `where` à cette colonne uniquement. Cest souvent plus lisible et performant que de faire un `CASE WHEN` imbriqué.
```sql ```sql
select count(distinct client) filter (where produit = 'pomme') select count(distinct client) filter (where produit = 'pomme')
from vente; from ligne;
``` ```
### Somme ### Somme
@@ -128,16 +130,10 @@ having count(t.id) = 72;
Avec postgreSQL et Microsoft SQL Server il n'est pas possible d'utiliser l'alias dans la condition having. La clause having intervient en amont du select dans le moteur d'exécution, l'alias n'est pas encore connu. Il faut réécrire la formule. Avec postgreSQL et Microsoft SQL Server il n'est pas possible d'utiliser l'alias dans la condition having. La clause having intervient en amont du select dans le moteur d'exécution, l'alias n'est pas encore connu. Il faut réécrire la formule.
## Agrégats d'intervalles
postgreSQL support un type particulier que sont les intervalles de valeur en définitissant dans un même champ une borne inférieure et une supérieure.
`range_agg` fusionne les intervalles tandis que `range_intersect_agg` retourne l'intersection.
## Agrégats statistiques ## Agrégats statistiques
Les aggrégats statistiques fonctionnent suivant 2 modes soit sur la pouplation totale (POP) soit sur des échantillons (SAMP) restreints. Les aggrégats statistiques fonctionnent suivant 2 modes soit sur la pouplation totale (**POP**) soit sur des échantillons (**SAMP**) restreints.
### Variance et écart type ### Variance et écart type
@@ -159,7 +155,7 @@ la fonction `corr` calcule le oefficient de corrélation linéaire de Pearson.
### Médiane et percentiles ### Médiane et percentiles
```sql ```sql
PERCENTILE_CONT(fraction) WITHIN GROUP (ORDER BY expr) percentile_cont(fraction) within group (order by expr)
``` ```
Calcule le quantile de manière continue (avec une interpolation des valeurs si besoin). Calcule le quantile de manière continue (avec une interpolation des valeurs si besoin).
@@ -179,15 +175,15 @@ MODE() WITHIN GROUP (ORDER BY expr)
Retourne la valeur la plus fréquente. Retourne la valeur la plus fréquente.
# Rang ## Rang
`rank`, `percent_rank` et `dense_rank` calcule le rang de la données. `rank`, `percent_rank` et `dense_rank` calcule le rang de la données.
`cume_dist` calcule la distribution cumulée. `cume_dist` calcule la distribution cumulée.
Ces fonctions sont en réalité des fenêtres analytiques mais peuvent être utilisées pour explorer la distribution. Exemple pour répartir en quartiles Ces fonctions sont en réalité des [fenêtres analytiques](window.md) mais peuvent être utilisées pour explorer la distribution.
# Régressions linéaires simples ## Régressions linéaires simples
Ces fonctions permettent de réaliser des régressions linéaires simples directement en SQL, cest-à-dire dajuster une droite de tendance entre deux ensembles de données numériques (variables x et y). Ces fonctions permettent de réaliser des régressions linéaires simples directement en SQL, cest-à-dire dajuster une droite de tendance entre deux ensembles de données numériques (variables x et y).
@@ -200,11 +196,44 @@ La régression linéaire simple cherche une droite : y = a⋅x + b
- a est la pente (slope). - a est la pente (slope).
- b est lordonnée à lorigine (intercept), - b est lordonnée à lorigine (intercept),
`REGR_SLOPE(y, x)` Calcule la pente de la droite (a), REGR_INTERCEPT(y, x) Calcule lordonnée à lorigine (b). <svg xmlns="http://www.w3.org/2000/svg" width="355" height="342.5" viewBox="0 0 355 342.5">
<defs>
<marker
id="arrow"
viewBox="0 0 10 10"
refX="5"
refY="5"
markerWidth="9"
markerHeight="9"
orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
</defs>
<line x1="30" y1="330" x2="30" y2="13" stroke="#000" marker-end="url(#arrow)" />
<line x1="10" y1="312.5" x2="330" y2="312" stroke="#000" marker-end="url(#arrow)" />
<path stroke="#000" d="M55 317.5v-10M80 317.5v-10M105 317.5v-10M130 317.5v-10M155 317.5v-10M180 317.5v-10M205 317.5v-10M230 317.5v-10M255 317.5v-10M280 317.5v-10M305 317.5v-10M25 287.5h10M25 262.5h10M25 237.5h10M25 212.5h10M25 187.5h10M25 162.5h10M25 137.5h10M25 112.5h10M25 87.5h10M25 62.5h10M25 37.5h10"/>
<g fill="#008">
<ellipse rx="4" ry="4" cx="205" cy="186.5" />
<ellipse rx="4" ry="4" cx="155" cy="213.75" />
<ellipse rx="4" ry="4" cx="280" cy="198" />
<ellipse rx="4" ry="4" cx="180" cy="167.25" />
<ellipse rx="4" ry="4" cx="230" cy="179.25" />
<ellipse rx="4" ry="4" cx="305" cy="138.5" />
<ellipse rx="4" ry="4" cx="105" cy="206.5" />
<ellipse rx="4" ry="4" cx="55" cy="281" />
<ellipse rx="4" ry="4" cx="255" cy="116.5" />
<ellipse rx="4" ry="4" cx="130" cy="267" />
<ellipse rx="4" ry="4" cx="80" cy="245.5" />
</g>
<path stroke="#f00" d="M10 275l500-250" stroke-width="2.5"/>
</svg>
REGR_COUNT(y, x) Nombre de paires (x, y) effectivement utilisées (hors NULL). Équivalent à COUNT(*) mais appliqué seulement sur les deux colonnes non nulles.
REGR_R2(y, x) Coefficient de détermination (entre 0 et 1). `REGR_SLOPE(y, x)` Calcule la pente de la droite (a),
`REGR_INTERCEPT(y, x)` Calcule lordonnée à lorigine (b).
`REGR_R2(y, x)` Coefficient de détermination (entre 0 et 1).
Mesure la qualité de lajustement : Mesure la qualité de lajustement :
@@ -212,3 +241,11 @@ Mesure la qualité de lajustement :
- 0 : aucun lien linéaire, - 0 : aucun lien linéaire,
plus cest proche de 1, plus la droite est pertinente. plus cest proche de 1, plus la droite est pertinente.
`REGR_COUNT(y, x)` Nombre de paires (x, y) effectivement utilisées (hors NULL) pour effectuer le calcul. Équivalent à COUNT(*) mais appliqué seulement sur les deux colonnes non nulles.
## Agrégats d'intervalles
postgreSQL support un type particulier que sont les [intervalles de valeur](intervalle.md) en définitissant dans un même champ une borne inférieure et une supérieure.
`range_agg` fusionne les intervalles tandis que `range_intersect_agg` retourne l'intersection.

@@ -18,9 +18,16 @@ Parce quelle doit produire une table (un jeu de résultats) indépendante **a
- Dans le SELECT, une sous-requête peut être corrélée (elle utilise des colonnes de la requête principale) ou non. - Dans le SELECT, une sous-requête peut être corrélée (elle utilise des colonnes de la requête principale) ou non.
- Dans le WHERE, idem : elle peut être corrélée (EXISTS, IN dépendant de la ligne en cours) ou non (test fixe). - Dans le WHERE, idem : elle peut être corrélée (EXISTS, IN dépendant de la ligne en cours) ou non (test fixe).
```sql
select * from article a1 where prix > (
select avg(prix) from article
where famille_code = a1.famille_code
)
```
## Sous-requête scalaire ## Sous-requête scalaire
une sous-requête scalaire est une sous-requête qui retourne une seule valeur (un scalaire, cest-à-dire une seule ligne et une seule colonne). > une sous-requête scalaire est une sous-requête qui retourne **une seule valeur** (un scalaire, cest-à-dire une seule ligne et une seule colonne).
Elle peut être utilisée partout où une valeur simple est attendue, par exemple : Elle peut être utilisée partout où une valeur simple est attendue, par exemple :
@@ -39,6 +46,13 @@ WHERE nom_colonne = (
) )
``` ```
Sélection des articles dont le prix est supérieur à la moyenne des prix de tous les articles
```sql
select * from article
where prix > (select avg(prix) from article);
```
## Conditions ## Conditions
### Exists ### Exists

@@ -203,3 +203,26 @@ n lignes/valeurs après la ligne courante
#### unbouded following #### unbouded following
jusquà la fin de la partition jusquà la fin de la partition
## Exercices
```sql
select * ,
lag(total) over (order by mois) as total_mois_p,
total - lag(total) over (order by mois) as difference,
lag(total, 12) over (order by mois) as total_annee_p
from ca_mensuel
order by mois
```
### Moyenne glissante sur 3 mois
```sql
select *, round(AVG(total) over (
order by mois
rows between 2 preceding and current row
), 2) as moyenne_glissante_3
from ca_mensuel
order by mois
```