Intervalle

2025-09-06 17:25:47 +02:00
parent 0747417319
commit 249ff64a60
4 changed files with 712 additions and 11 deletions

23
Calculated.md Normal file

@@ -0,0 +1,23 @@
# Calcul
## Volatilité
> La volatilité indique au moteur postgreSQL à quel point le résultat de la fonction dépend de létat de la base ou du contexte. Il existe 3 niveaux.
### IMMUTABLE
Le résultat **ne change jamais** pour les mêmes arguments.
Exemple : abs(-5) donne toujours 5, peu importe quand ou où la fonction est exécutée.
Utilisable dans : index, colonnes calculées, contraintes CHECK, etc.
### STABLE
Le résultat ne change pas pendant une requête donnée, mais **peut changer entre deux requêtes**.
La fonction `ST_Length(geom)` est STABLE car pour une même géométrie, la longueur est toujours la même, MAIS cela dépend de paramètres de la session (SRID de référence).
### VOLATILE
Le résultat peut changer même dans une seule requête. Par exemple : `random()` ou `now()` donnent des résultats différents à chaque appel.

@@ -5,8 +5,9 @@
- [Sous requêtes](sousrequete.md)
- [Vues et fonctions](View.md)
- [Fonctions de fenêtrage](window.md)
- [Données spatiales](Spatial.md)
- [Intervalles](intervalle.md)
- [Arbres](Arbres.md)
- [Données spatiales](Spatial.md)
## Exercices

678
Spatial.AI.md Normal file

@@ -0,0 +1,678 @@
Oui 👍
Cest tout à fait possible avec **pgRouting**, car le moteur ne « devine » pas la praticabilité : cest vous qui la décrivez dans la table de graphes (souvent une table `ways`).
---
### 🔑 Principe
* Chaque **arête (tronçon de route)** a un coût (`cost`) et éventuellement un coût inverse (`reverse_cost`).
* Ces coûts peuvent être calculés différemment **selon le mode de transport** (voiture, vélo, piéton, etc.).
* Si une voie est **interdite** pour un mode, on met son `cost` (ou `reverse_cost`) à `-1` → cela signifie *inaccessible*.
---
### 🏷️ Exemple de modèle de données
Supposons une table `roads` :
```sql
CREATE TABLE roads (
id SERIAL PRIMARY KEY,
source INTEGER,
target INTEGER,
length FLOAT,
type VARCHAR(50) -- ex: motorway, residential, footway
);
```
Vous pouvez enrichir avec des colonnes spécifiques au mode de transport :
```sql
ALTER TABLE roads ADD COLUMN car_cost FLOAT;
ALTER TABLE roads ADD COLUMN bike_cost FLOAT;
ALTER TABLE roads ADD COLUMN foot_cost FLOAT;
```
---
### 🚘 Exemple daffectation des coûts
* Une rue normale (`residential`) → accessible à tous
* Une ruelle piétonne (`footway`) → inaccessible en voiture
```sql
UPDATE roads
SET car_cost = length,
bike_cost = length,
foot_cost = length
WHERE type = 'residential';
UPDATE roads
SET car_cost = -1, -- interdit aux voitures
bike_cost = length,
foot_cost = length
WHERE type = 'footway';
```
---
### 📌 Utilisation avec pgRouting
Quand vous appelez une fonction comme `pgr_dijkstra`, vous spécifiez **quelle colonne sert de coût** :
* Pour la voiture :
```sql
SELECT * FROM pgr_dijkstra(
'SELECT id, source, target, car_cost AS cost, car_cost AS reverse_cost FROM roads',
1, 10
);
```
* Pour le vélo :
```sql
SELECT * FROM pgr_dijkstra(
'SELECT id, source, target, bike_cost AS cost, bike_cost AS reverse_cost FROM roads',
1, 10
);
```
* Pour les piétons :
```sql
SELECT * FROM pgr_dijkstra(
'SELECT id, source, target, foot_cost AS cost, foot_cost AS reverse_cost FROM roads',
1, 10
);
```
---
✅ Résultat : vous pouvez définir autant de « profils de transport » que vous voulez (voiture, vélo, camion, livraison, pompier, etc.) simplement en gérant des colonnes de coûts adaptées.
---
Voulez-vous que je prépare un **mini-script SQL complet** (création de table + 4 routes + 2 modes de transport) pour que vous puissiez le tester directement dans PostgreSQL + pgRouting ?
## Ce n'est pas terrible ! Il faut deux colonnes par mode de transport
Vous avez raison 👌 : si on fait **une colonne `cost` et `reverse_cost` par mode de transport**, ça double vite et ça devient lourd (car + vélo + piéton + camion → 8 colonnes à gérer).
Heureusement il y a plusieurs approches plus élégantes avec **pgRouting** :
---
## 🔹 1. Table des restrictions (plus flexible)
Au lieu de mettre les coûts dans la table des routes, on les externalise dans une table de profils :
```sql
CREATE TABLE road_costs (
road_id INT,
mode TEXT, -- 'car', 'bike', 'foot', etc.
cost FLOAT,
reverse_cost FLOAT,
PRIMARY KEY (road_id, mode)
);
```
Exemple dinsertion :
```sql
-- Route résidentielle
INSERT INTO road_costs VALUES (1, 'car', 100, 100);
INSERT INTO road_costs VALUES (1, 'bike', 100, 100);
INSERT INTO road_costs VALUES (1, 'foot', 100, 100);
-- Ruelle piétonne
INSERT INTO road_costs VALUES (2, 'car', -1, -1); -- inaccessible
INSERT INTO road_costs VALUES (2, 'bike', 80, 80);
INSERT INTO road_costs VALUES (2, 'foot', 50, 50);
```
Ensuite, pour calculer un itinéraire en voiture :
```sql
SELECT * FROM pgr_dijkstra(
'SELECT r.id, r.source, r.target, c.cost, c.reverse_cost
FROM roads r
JOIN road_costs c ON r.id = c.road_id
WHERE c.mode = ''car''',
1, 10
);
```
👉 Avantage :
* Plus propre, **une seule table de routes**.
* Ajout dun nouveau mode = juste quelques lignes dans `road_costs`.
---
## 🔹 2. Encodage JSON / hstore (si vous voulez rester dans une seule table)
On peut stocker les coûts sous forme JSON dans `roads` :
```sql
ALTER TABLE roads ADD COLUMN costs JSONB;
```
Exemple de données :
```sql
UPDATE roads SET costs = '{
"car": {"cost": 100, "reverse_cost": 100},
"bike": {"cost": 100, "reverse_cost": 100},
"foot": {"cost": 100, "reverse_cost": 100}
}' WHERE id = 1;
UPDATE roads SET costs = '{
"car": {"cost": -1, "reverse_cost": -1},
"bike": {"cost": 80, "reverse_cost": 80},
"foot": {"cost": 50, "reverse_cost": 50}
}' WHERE id = 2;
```
Puis extraire dynamiquement le mode :
```sql
SELECT * FROM pgr_dijkstra(
$$
SELECT id, source, target,
(costs->'car'->>'cost')::float AS cost,
(costs->'car'->>'reverse_cost')::float AS reverse_cost
FROM roads
$$,
1, 10
);
```
👉 Avantage :
* Une seule table, extensible.
* Flexible si vous voulez ajouter "bus", "camion", etc.
---
## 🔹 3. Génération dynamique de la vue
Une autre approche : vous gardez juste la longueur et le type de route dans `roads`, puis vous créez une **vue par mode de transport** qui applique les règles.
Exemple :
```sql
CREATE VIEW roads_car AS
SELECT id, source, target,
CASE WHEN type = 'footway' THEN -1 ELSE length END AS cost,
CASE WHEN type = 'footway' THEN -1 ELSE length END AS reverse_cost
FROM roads;
```
Ensuite :
```sql
SELECT * FROM pgr_dijkstra('SELECT * FROM roads_car', 1, 10);
```
👉 Avantage : pas de duplication des colonnes, règles exprimées en SQL.
---
🔧 **En pratique** :
* Si vous voulez un truc simple → solution **vue par mode de transport**.
* Si vous voulez un système extensible et propre → solution **table des restrictions**.
* Si vous aimez tout stocker dans une seule colonne → solution **JSONB**.
---
Souhaitez-vous que je vous prépare un **exemple concret avec la solution JSONB** (plus moderne et compacte), ou bien préférez-vous la version **table des restrictions** (plus SQL pur) ?
Je pensais plutôt à une table Many-To-Many de tags. Ensuite la requête exclu les routes qui ont un tag spécifique (par exemple voie à péage) ou au contraire avec uniquement avec un tag particulier (voie cyclable protégée)
Oui, excellente idée 👌 !
Cest beaucoup plus **proche du modèle OpenStreetMap**, où chaque tronçon de route peut avoir plusieurs attributs (*tags*), et où un même tag peut concerner plusieurs routes.
---
## 🔹 Modèle Many-to-Many avec tags
### Table des routes
```sql
CREATE TABLE roads (
id SERIAL PRIMARY KEY,
source INT,
target INT,
length FLOAT
);
```
### Table des tags
```sql
CREATE TABLE tags (
id SERIAL PRIMARY KEY,
name TEXT UNIQUE
);
```
### Table de liaison routes ↔ tags
```sql
CREATE TABLE road_tags (
road_id INT REFERENCES roads(id) ON DELETE CASCADE,
tag_id INT REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (road_id, tag_id)
);
```
---
## 🔹 Exemple de données
Tags de référence :
```sql
INSERT INTO tags (name) VALUES
('footway'), ('cycleway'), ('toll'), ('residential');
```
Routes :
```sql
INSERT INTO roads (id, source, target, length) VALUES
(1, 1, 2, 100),
(2, 2, 3, 80),
(3, 3, 4, 120),
(4, 4, 5, 60);
```
Associer les tags :
```sql
-- Route 1 = résidentielle
INSERT INTO road_tags VALUES (1, (SELECT id FROM tags WHERE name='residential'));
-- Route 2 = piétonne
INSERT INTO road_tags VALUES (2, (SELECT id FROM tags WHERE name='footway'));
-- Route 3 = voie à péage
INSERT INTO road_tags VALUES (3, (SELECT id FROM tags WHERE name='toll'));
-- Route 4 = piste cyclable
INSERT INTO road_tags VALUES (4, (SELECT id FROM tags WHERE name='cycleway'));
```
---
## 🔹 Utilisation dans pgRouting
### Exemple : exclure les routes à péage
```sql
SELECT * FROM pgr_dijkstra(
$$
SELECT r.id, r.source, r.target, r.length AS cost, r.length AS reverse_cost
FROM roads r
WHERE NOT EXISTS (
SELECT 1 FROM road_tags rt
JOIN tags t ON rt.tag_id = t.id
WHERE rt.road_id = r.id AND t.name = 'toll'
)
$$,
1, 5
);
```
---
### Exemple : nautoriser **que les pistes cyclables**
```sql
SELECT * FROM pgr_dijkstra(
$$
SELECT r.id, r.source, r.target, r.length AS cost, r.length AS reverse_cost
FROM roads r
WHERE EXISTS (
SELECT 1 FROM road_tags rt
JOIN tags t ON rt.tag_id = t.id
WHERE rt.road_id = r.id AND t.name = 'cycleway'
)
$$,
1, 5
);
```
---
## ✅ Avantages de ce modèle
* Très extensible (on peut gérer des dizaines de tags comme dans OSM).
* Pas besoin dajouter une colonne par mode ou contrainte.
* Les requêtes pgRouting filtrent dynamiquement en fonction des tags.
---
👉 Souhaitez-vous que je vous prépare un **script complet (DDL + INSERT + requêtes pgRouting)** avec 2-3 exemples ditinéraires (voiture, vélo, piéton) pour que vous puissiez le tester directement ?
L'externalisation du coût est pas mal car en vélo les montées sont plus pénalisantes que les descentes. Alors qu'en voiture la différence est négligeable sauf sur des très grosses pentes.
Je pensais plutôt à une table Many-To-Many de tags. Ensuite la requête exclu les routes qui ont un tag spécifique (par exemple voie à péage) ou au contraire avec uniquement avec un tag particulier (voie cyclable protégée)
Comment rajouter les règles routes à péage interdites au vélo, chemins forestiers interdits à la voiture. Avec des tags ?
Exactement ✔️
On peut exprimer ce genre de règles avec des **tags** (comme dans OpenStreetMap) et les appliquer **au moment de calculer les coûts** pour un mode de transport.
---
## 🔹 1. Tables de base
```sql
CREATE TABLE roads (
id SERIAL PRIMARY KEY,
source INT,
target INT,
length FLOAT
);
CREATE TABLE tags (
id SERIAL PRIMARY KEY,
name TEXT UNIQUE
);
CREATE TABLE road_tags (
road_id INT REFERENCES roads(id) ON DELETE CASCADE,
tag_id INT REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (road_id, tag_id)
);
```
---
## 🔹 2. Exemple de tags
```sql
INSERT INTO tags (name) VALUES
('toll'), -- route à péage
('forest'), -- chemin forestier
('cycleway'), -- piste cyclable
('footway'), -- voie piétonne
('residential'); -- route normale
```
---
## 🔹 3. Génération des coûts par mode
On externalise les coûts avec une logique conditionnelle basée sur les tags.
Par exemple :
```sql
CREATE TABLE road_costs (
road_id INT REFERENCES roads(id),
mode TEXT,
cost FLOAT,
reverse_cost FLOAT,
PRIMARY KEY (road_id, mode)
);
```
Puis on remplit avec des règles :
### Vélo
* Routes normales = distance
* Routes à péage (`toll`) = interdit (`-1`)
* Escaliers (`footway`) = interdit (`-1`)
* Pistes cyclables (`cycleway`) = bonus (coût réduit)
```sql
INSERT INTO road_costs
SELECT r.id, 'bike',
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='toll') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='cycleway') THEN r.length * 0.7
ELSE r.length
END AS cost,
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='toll') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='cycleway') THEN r.length * 0.7
ELSE r.length
END AS reverse_cost
FROM roads r;
```
---
### 🚗 Voiture
* Routes normales = distance
* Chemins forestiers (`forest`) = interdits (`-1`)
* Voies piétonnes (`footway`) = interdites (`-1`)
```sql
INSERT INTO road_costs
SELECT r.id, 'car',
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='forest') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
ELSE r.length
END AS cost,
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='forest') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
ELSE r.length
END AS reverse_cost
FROM roads r;
```
---
## 🔹 4. Utilisation dans pgRouting
Pour calculer un itinéraire vélo :
```sql
SELECT * FROM pgr_dijkstra(
'SELECT r.id, r.source, r.target, c.cost, c.reverse_cost
FROM roads r
JOIN road_costs c ON r.id = c.road_id
WHERE c.mode = ''bike''',
1, 10
);
```
Pour la voiture :
```sql
SELECT * FROM pgr_dijkstra(
'SELECT r.id, r.source, r.target, c.cost, c.reverse_cost
FROM roads r
JOIN road_costs c ON r.id = c.road_id
WHERE c.mode = ''car''',
1, 10
);
```
---
✅ Avantage :
* Les règles sont **lisibles** et **évolutives**.
* On reste dans la logique OSM (tags multiples, requêtes qui filtrent).
* Si demain vous ajoutez un nouveau mode (`truck`, `bus`, `emergency`), vous ne changez pas la structure, juste la logique dinsertion des coûts.
---
👉 Voulez-vous que je prépare un **exemple exécutable complet** (création de tables, insertion de 4 routes avec tags variés, et 2 requêtes pgRouting avec résultats différents vélo vs voiture) ?
Oui j'aimerais un exemple exécutable complet
Parfait ✅, voici un **exemple SQL complet** que vous pouvez exécuter directement dans **PostgreSQL + PostGIS + pgRouting**.
Il illustre :
* une petite base de 4 routes (5 nœuds),
* des **tags** associés aux routes,
* un calcul de coût différent selon le mode (🚲 vélo vs 🚗 voiture),
* et un itinéraire avec `pgr_dijkstra`.
---
## 📌 Script SQL complet
```sql
-- Extension nécessaire
CREATE EXTENSION IF NOT EXISTS pgrouting;
-- ====================================
-- 1. Tables de base
-- ====================================
DROP TABLE IF EXISTS road_costs CASCADE;
DROP TABLE IF EXISTS road_tags CASCADE;
DROP TABLE IF EXISTS tags CASCADE;
DROP TABLE IF EXISTS roads CASCADE;
CREATE TABLE roads (
id SERIAL PRIMARY KEY,
source INT,
target INT,
length FLOAT
);
CREATE TABLE tags (
id SERIAL PRIMARY KEY,
name TEXT UNIQUE
);
CREATE TABLE road_tags (
road_id INT REFERENCES roads(id) ON DELETE CASCADE,
tag_id INT REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (road_id, tag_id)
);
CREATE TABLE road_costs (
road_id INT REFERENCES roads(id),
mode TEXT,
cost FLOAT,
reverse_cost FLOAT,
PRIMARY KEY (road_id, mode)
);
-- ====================================
-- 2. Données de test
-- Graphe simple : 5 nœuds reliés par 4 routes
-- ====================================
INSERT INTO roads (id, source, target, length) VALUES
(1, 1, 2, 100), -- route normale
(2, 2, 3, 80), -- route à péage
(3, 3, 4, 120), -- chemin forestier
(4, 4, 5, 60); -- piste cyclable
-- Tags
INSERT INTO tags (name) VALUES
('toll'), ('forest'), ('cycleway'), ('footway'), ('residential');
-- Attribution des tags aux routes
INSERT INTO road_tags VALUES (1, (SELECT id FROM tags WHERE name='residential'));
INSERT INTO road_tags VALUES (2, (SELECT id FROM tags WHERE name='toll'));
INSERT INTO road_tags VALUES (3, (SELECT id FROM tags WHERE name='forest'));
INSERT INTO road_tags VALUES (4, (SELECT id FROM tags WHERE name='cycleway'));
-- ====================================
-- 3. Génération des coûts par mode
-- ====================================
-- 🚲 Vélo :
-- - interdit sur péage et footway
-- - bonus sur piste cyclable (0.7)
-- - normal sinon
INSERT INTO road_costs
SELECT r.id, 'bike',
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='toll') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='cycleway') THEN r.length * 0.7
ELSE r.length
END AS cost,
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='toll') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='cycleway') THEN r.length * 0.7
ELSE r.length
END AS reverse_cost
FROM roads r;
-- 🚗 Voiture :
-- - interdit sur chemins forestiers et footways
-- - normal sinon
INSERT INTO road_costs
SELECT r.id, 'car',
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='forest') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
ELSE r.length
END AS cost,
CASE
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='forest') THEN -1
WHEN EXISTS (SELECT 1 FROM road_tags rt JOIN tags t ON rt.tag_id=t.id WHERE rt.road_id=r.id AND t.name='footway') THEN -1
ELSE r.length
END AS reverse_cost
FROM roads r;
-- ====================================
-- 4. Test des itinéraires
-- ====================================
-- Itinéraire vélo du nœud 1 à 5
SELECT * FROM pgr_dijkstra(
$$
SELECT r.id, r.source, r.target, c.cost, c.reverse_cost
FROM roads r
JOIN road_costs c ON r.id = c.road_id
WHERE c.mode = 'bike'
$$,
1, 5
);
-- Itinéraire voiture du nœud 1 à 5
SELECT * FROM pgr_dijkstra(
$$
SELECT r.id, r.source, r.target, c.cost, c.reverse_cost
FROM roads r
JOIN road_costs c ON r.id = c.road_id
WHERE c.mode = 'car'
$$,
1, 5
);
```
---
## 📊 Résultat attendu
* **Pour le vélo** :
* Route 2 (péage) est interdite (`-1`) → lalgorithme ne la prend pas.
* Route 4 (piste cyclable) a un coût réduit (`60 * 0.7 = 42`).
* Litinéraire 1 → 2 est OK, mais ensuite le péage bloque, donc vélo prendra **1 → 2 (ok) → \[pas 2→3 car péage interdit] → échec**.
* Donc il ny a pas de chemin complet de 1 à 5 en vélo (dans ce petit graphe).
* **Pour la voiture** :
* Route 3 (forest) est interdite, donc bloquée.
* La voiture peut faire 1 → 2 (100) → 3 (80, péage autorisé) → \[bloqué en 3→4 car forest].
* Pas de chemin complet non plus en voiture.
👉 Ce petit graphe est volontairement minimaliste : il montre que **chaque mode a ses contraintes** et peut bloquer certains trajets. Dans un vrai graphe (issu dOSM), vous auriez des alternatives valides.
---
Voulez-vous que je complète cet exemple avec **un graphe légèrement plus grand (6-7 routes)** pour que les itinéraires vélo et voiture aboutissent bien avec des chemins différents ?

@@ -6,7 +6,7 @@ Un intervalle possède un début d et une fin f, tels que d < f.
Les types de plage sont utiles car ils représentent de nombreuses valeurs déléments dans une seule valeur de plage et parce que des concepts tels que les plages qui se chevauchent peuvent être exprimés clairement. Lutilisation de plages dheures et de dates à des fins de planification en est lexemple le plus clair ; mais les fourchettes de prix, les plages de mesure d'un instrument, etc. peuvent également être utiles.
Les types de plage sont des types de données représentant une plage de valeurs d'un certain type d'élément (appelé sous-type de plage). Par exemple, des plages dhorodatage peuvent être utilisées pour représenter les plages horaires pendant lesquelles une salle de réunion est réservée. Dans ce cas, le type de données est tsrange (abréviation de « timestamp range ») et timestamp est le sous-type.
Les types de plage sont des types de données représentant une plage de valeurs d'un certain type d'élément (appelé sous-type de plage). Par exemple, des plages dhorodatage peuvent être utilisées pour représenter les plages horaires pendant lesquelles une salle de réunion est réservée. Dans ce cas, le type de données est tsrange (abréviation de « timestamp range ») et timestamp est le sous-type.
## Types
@@ -38,24 +38,23 @@ SELECT '[10,20)'::int4range;
Chaque plage non vide a deux limites, la limite inférieure et la limite supérieure. Tous les points entre ces valeurs sont inclus dans la plage. Une limite inclusive signifie que le point limite lui-même est également inclus dans la plage, tandis qu'une limite exclusive signifie que le point limite n'est pas inclus dans la plage.
Dans la forme textuelle d'une plage, les limites inclusives sont représentées par des crochets `[` et `]` tandis que les limites exclusives sont représentées par des parenthèses `(` et `)`.
Dans la forme textuelle d'une plage, les limites inclusives sont représentées par des crochets `[` et `]` tandis que les limites exclusives sont représentées par des parenthèses `(` et `)`.
Les fonctions lower_inc et upper_inc testent respectivement l'inclusivité des limites inférieure et supérieure d'une valeur de plage.
## Plages infinies (illimitées)
La limite inférieure d'une plage peut être omise, ce qui signifie que toutes les valeurs inférieures à la limite supérieure sont incluses, par exemple `(,3)`. De même, si la limite supérieure de la plage est omise, alors toutes les valeurs supérieures à la limite supérieure de la plage le sont.
La limite inférieure d'une plage peut être omise, ce qui signifie que toutes les valeurs inférieures à la limite supérieure sont incluses, par exemple `(,3)`. De même, si la limite supérieure de la plage est omise, alors toutes les valeurs supérieures à la limite supérieure de la plage le sont.
Les fonctions lower_inf et upper_inf testent respectivement les limites inférieure et supérieure infinies d'une plage.
## Logique dintervalles dAllen
> Logique dintervalles dAllen : ensemble complet dopérateurs booléens de base pour le positionnement relatif dans le temps.
> Ensemble complet dopérateurs booléens de base pour le positionnement relatif dans le temps.
Deux intervalles A et B peuvent se positionner selon 13 configurations.
Deux intervalles A et B peuvent se positionner selon **13 configurations**.
### 1. Précède
@@ -174,7 +173,7 @@ A se déroule _Pendant_ (during) B lorque la borne inférieure de A est supérie
Allen|Postgres
------|---
A d B | A <@ B
A d B | A <@ B
```sql
select '[7,10]'::int4range <@ '[5,14]'::int4range;
@@ -188,7 +187,7 @@ A _Contient_ B lorsque la borne inférieure de A est inférieure à la borne inf
Allen |Postgres
------|---
A di B | A @> B
A di B | A @> B
<svg viewbox="0 0 20 8" width="200" height="80">
<text x="5" y="3" font-size="1.8" text-anchor="middle">A</text>
@@ -237,7 +236,7 @@ A _Finit_ en même temps (finishes) que B lorsque la borne supérieure de A est
Allen|Postgres
------|---
A f B | A &< B
A f B | A &< B
```sql
select '[5,15]'::int4range &< '[10,15]'::int4range;