PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#26 Général » [RESOLU] Avis sur requête (fenêtrage ?) » 17/04/2014 15:42:22

Thomas Williamson
Réponses : 5

Bonjour,


Je souhaiterais avoir votre avis concernant la requête ci-dessous, afin que je sache si on peut faire plus simple ou non (les fonctions de fenêtrage peut-être ?). En résumé, j'interroge une unique table stockant des tronçons de réseau d'eau, dans laquelle j'ai une colonne géométrie stockant la forme et le positionnement de chaque tronçon et une colonne stockant la date de pose. Je souhaite calculer un pourcentage du linéaire en fonction de la date de pose. Ma requête me donne le résultat suivant :


 periode        | pourcent
----------------+-----------
 2005 - 2014    | 18.6
 1995 - 2004    | 16.1
 1985 - 1994    | 7.6
 1975 - 1984    | 19.0
 1965 - 1974    | 28.2
 1945 - 1964    | 10.2
 avant 1945     | 0.1
WITH total AS (SELECT sum(st_length(geom)) AS longueur_totale FROM c_3_0_3 WHERE datpose IS NOT NULL)

SELECT '2005 - 2014'::VARCHAR(11) AS periode, ((sum(st_length(geom))*100)/longueur_totale) AS pourcent FROM c_3_0_3, total WHERE datpose BETWEEN 2005 AND 2014 GROUP BY longueur_totale
union all
SELECT '1995 - 2004'::VARCHAR(11) AS periode, ((sum(st_length(geom))*100)/longueur_totale) AS pourcent FROM c_3_0_3, total WHERE datpose BETWEEN 1995 AND 2004 GROUP BY longueur_totale
union all
SELECT '1985 - 1994'::VARCHAR(11) AS periode, ((sum(st_length(geom))*100)/longueur_totale) AS pourcent FROM c_3_0_3, total WHERE datpose BETWEEN 1985 AND 1994 GROUP BY longueur_totale
union all
SELECT '1975 - 1984'::VARCHAR(11) AS periode, ((sum(st_length(geom))*100)/longueur_totale) AS pourcent FROM c_3_0_3, total WHERE datpose BETWEEN 1975 AND 1984 GROUP BY longueur_totale
union all
SELECT '1965 - 1674'::VARCHAR(11) AS periode, ((sum(st_length(geom))*100)/longueur_totale) AS pourcent FROM c_3_0_3, total WHERE datpose BETWEEN 1965 AND 1974 GROUP BY longueur_totale
union all
SELECT '1945 - 1964'::VARCHAR(11) AS periode, ((sum(st_length(geom))*100)/longueur_totale) AS pourcent FROM c_3_0_3, total WHERE datpose BETWEEN 1945 AND 1964 GROUP BY longueur_totale
union all
SELECT 'avant 1945'::VARCHAR(11) AS periode, ((sum(st_length(geom))*100)/longueur_totale) AS pourcent FROM c_3_0_3, total WHERE datpose <= 1944 GROUP BY longueur_totale ;

Merci pour vos avis !


Thomas

#28 Re : Général » [RESOLU] COPY TO serveur > local » 14/03/2014 14:58:20

Merci. J'ai fais des recherches pour utiliser le terminal psql, du coup. Je cherche à indiquer dans la commande le répertoire local où je souhaite enregistrer mon fichier csv.


J'en suis là mais sans succès :


ma_base=# \copy schema.table to stdout with csv header

Je suis visiblement obligé d'utiliser stdout pour envoyer l'export vers le poste client (mon poste, en local) mais dans ce cas, je ne vois pas comment spécifier un nom de fichier et un chemin d'accès...


Thomas

#29 Général » [RESOLU] COPY TO serveur > local » 14/03/2014 13:06:14

Thomas Williamson
Réponses : 4

Bonjour,


Je cherche à exporter une table en local depuis ma base de données qui est sur un serveur distant et j'ai quelques difficultés pour utiliser la commande COPY... TO... (je suis sur Windows et le serveur distant également).


Voici la requête exécutée depuis pgAdmin et l'erreur renvoyée :

COPY schema.table TO 'D:\\test.csv' WITH CSV ;

ERREUR:  n'a pas pu ouvrir le fichier « D:\\test.csv » en écriture : Permission denied


La question est donc : comment indiquer dans le chemin d'accès que je souhaite écrire en local ? Est-il possible de passer l'adresse IP de mon poste ?



Merci pour votre aide,


Thomas

#30 Re : Général » [RESOLU] Aide sur une requête » 06/02/2014 10:55:41

Bonjour,


Test ce matin et ça fonctionne bien. Cela me permet de contourner le problème assez simplement même si je suis bien conscient que la modélisation est mauvaise...


Merci pour votre aide !


Thomas

#32 Re : Général » [RESOLU] Aide sur une requête » 05/02/2014 15:23:24

Bonjour,


C'est le 2e scénario qui est bon ! Au passage, je n'ai rien modélisé du tout... Je travaille sur ce tableau que j'ai récupéré. Ma question était juste de savoir si je pouvais sortir ce type de résultat sans avoir à remanier mon tableau. Sinon, je me rends bien compte que la modélisation n'est pas bonne. Existe-t-il une clause associée à un SELECT qui permettrait de faire un regroupement des forages par agence en se basant sur une seule occurrence de chaque commune ?


Thomas

#33 Re : Général » [RESOLU] Aide sur une requête » 05/02/2014 08:45:36

Bonjour,


Merci pour ton avis... En fait j'aurais voulu idéalement récupérer le nombre de forages par agence, donc un tableau de résultats du genre :


agence     ⎪  nb_forage
-----------+-------------
  1        ⎪  23
  2        ⎪  7
  3        ⎪  2

Bon, je me dirige plus vers une séparation de mes jeux de données (forages d'un côté et réservoirs de l'autre)...


Thomas

#34 Re : Général » [RESOLU] Aide sur une requête » 04/02/2014 21:03:35

Bonjour,


Je souhaiterais faire la somme du nombre de forages par agence, en ne retenant qu'une seule ligne par commune (puisque chaque ligne de commune dupliquée comporte le même nombre de forages). Ma question est donc de savoir si cela est possible dans une requête ou s'il convient que je sépare mon jeu de données en traitant séparément les ouvrages et les réservoirs. J'ai l'impression d'être un abruti de première, à la façon dont vous me répondez.


Merci pour votre aide (si j'en vaux la peine).


Thomas

#35 Général » [RESOLU] Aide sur une requête » 04/02/2014 17:06:54

Thomas Williamson
Réponses : 10

Bonjour,


J'ai la table suivante qui dénombre les forages et des réservoirs par commune (pour les réservoirs, on distingue le nombre suivant le type de réservoir) :


  agence    |  commune         |  nb_forage    |  type_reservoir    |  nb_reservoir
------------+------------------+---------------+--------------------+----------------
  1         |  86001           |  2            |  01                |  1
  1         |  86002           |  3            |  01                |  1
  1         |  86002           |  3            |  02                |  2
  2         |  86003           |  1            |  01                |  3
  2         |  86003           |  1            |  01                |  3
  2         |  86004           |  0            |  02                |  3

Je cherche à calculer le nombre de forages par agence. La requête ci-dessous me renvoie un résultat erroné car elle fait la somme des forages sans tenir compte du fait que certaines communes apparaissent deux fois. Cela paraît inévitable car les réservoirs sont par ailleurs dénombrés suivant le type de réservoir. Ainsi, si j'ai deux types de réservoirs sur une commune, j'ai deux lignes pour cette commune et donc le nombre de forages apparaît deux fois.


SELECT agence, sum(nb_forage) FROM maTable GROUP BY agence ;

Ma question : comment puis-je dénombrer les forages par agence en ne retenant qu'une seule ligne par commune ? Puis-je le faire plus simplement qu'en passant par une table temporaire avec un WITH ?


Merci pour votre aide !


Thomas

#36 Re : Général » [RESOLU] Afficher des mois non enregistrés » 21/01/2014 16:28:46

Super, merci beaucoup pour ton aide ! Ça fonctionne très bien à présent...


Thomas

#37 Re : Général » [RESOLU] Afficher des mois non enregistrés » 21/01/2014 15:53:23

Re !


En fait, j'avais glissé une clause WHERE qui semble bloquer la sortie des 12 mois (je n'ai plus le problème lorsque je la retire). Je l'avais retiré de mon exemple pour ne pas trop le surcharger, pensant que ça n'aurait pas d'effet sur le résultat. Bon, en fait si (et je ne vois pas pourquoi : le LEFT JOIN est sensé reprendre toutes les occurences de la table mois, non ?). Ma table operation stocke des dates sur plusieurs années donc je veux pouvoir faire des sommes mensuelles pour une année donnée.


Je mets ma requête complète :


WITH mois AS (SELECT num, to_char(to_timestamp(num::TEXT,'MM'), 'TMMonth') AS mois FROM generate_series(1,12) num)

SELECT 
 EXTRACT(MONTH FROM b.date)::SMALLINT AS num,
 a.mois AS mois,
 sum(b.temps::TIME) AS nb_heure 

FROM mois a
  LEFT JOIN schema.operation b ON EXTRACT(MONTH FROM b.date) = a.num

WHERE EXTRACT(YEAR FROM b.date) = '2013'

GROUP BY EXTRACT(MONTH FROM b.date), a.mois 

ORDER BY num ;

#38 Re : Général » [RESOLU] Afficher des mois non enregistrés » 21/01/2014 14:31:39

Bonjour,


J'ai modifié ma requête comme ci-dessous mais j'ai toujours des mois manquants...


WITH mois AS (SELECT num, to_char(to_timestamp(num::TEXT,'MM'), 'TMMonth') AS mois FROM generate_series(1,12) num)

SELECT 
 EXTRACT(MONTH FROM b.date)::SMALLINT AS num,
 a.mois AS mois,
 sum(b.temps::TIME) AS nb_heure 

FROM mois a
  LEFT JOIN schema.operation b ON EXTRACT(MONTH FROM b.date) = a.num

GROUP BY EXTRACT(MONTH FROM b.date), a.mois 

ORDER BY num ;

#39 Général » [RESOLU] Afficher des mois non enregistrés » 21/01/2014 11:40:59

Thomas Williamson
Réponses : 6

Bonjour,


J'ai une table avec la structure suivante :


CREATE TABLE operation (gid serial NOT NULL, date DATE, temps VARCHAR(5)) ;

Cette table comporte des dates (ex : 02/01/2013) et des périodes de temps (ex : 01:30). Je dais la somme des périodes de temps par mois avec la requête suivante :


SELECT 
 EXTRACT(MONTH FROM date)::SMALLINT AS num,
 to_char(date, 'TMMonth') AS mois,
 sum(temps::TIME) AS nb_heure 

FROM schema.operation 

GROUP BY EXTRACT(MONTH FROM date), to_char(date, 'TMMonth') 

ORDER BY num ; 

J'obtiens le tableau suivant :


num          mois               nb_heure
----------+-----------------+-------------
1         + Janvier         + 05:00:00
3         + Mars            + 02:30:00
4         + Avril           + 01:00:00
5         + Mai             + 01:00:00
6         + Juin            + 01:00:00
7         + Juillet         + 01:00:00
9         + Septembre       + 01:00:00
10        + Octobre         + 01:00:00
11        + Novembre        + 01:00:00
12        + Décembre        + 01:00:00

Ma question : Il manque certains mois pour lesquels aucune date ne fait référence dans la table operation... Comment pourrais-je constituer un tableau avec tous les mois de l'année par défaut (même si plusieurs sont à 00:00:00) ? J'ai pensé à faire un LEFT JOIN avec une table listant les mois mais je pense qu'il doit y avoir plus simple.


Merci d'avance pour vos avis sur ce sujet !


Thomas

#41 Général » [RESOLU] Extraire le mois d'une date en français » 21/01/2014 10:14:18

Thomas Williamson
Réponses : 2

Bonjour,


J'extrais le mois d'une date de la manière suivante ('date' est une colonne stockant des dates) :

SELECT to_char(date, 'Month') AS "mois" FROM schema.table ;

J'obtiens par exemple 'December' pour décembre. Comment pourrais-je obtenir 'Décembre' directement ? J'ai pensé à utiliser un CASE... END mais s'il y a plus simple, je suis preneur !



Merci par avance pour votre aide,


Thomas

#42 Re : Général » Recherche de valeurs entre deux tables » 14/11/2013 13:02:53

Bonjour,


Merci en effet ça marche mieux... J'avais aussi trouvé ça entre temps :

SELECT gid FROM table_a WHERE gid NOT IN (SELECT gid FROM table_b) ;

Thomas

#43 Général » Recherche de valeurs entre deux tables » 14/11/2013 12:02:54

Thomas Williamson
Réponses : 2

Bonjour,


J'essaie de ressortir les valeurs d'une table a qui ne se trouvent pas dans une table b :

CREATE TABLE table_a (gid varchar(2)) ;
INSERT INTO table_a (gid) VALUES ('01', '02', '03', '04', '05') ;
CREATE TABLE table_b (gid varchar(2)) ;
INSERT INTO table_b (gid) VALUES ('06', '02', '07', '08', '09') ;

La requête suivante me renvoie les valeurs 01, 02, 03, 04 et 05 alors que la valeur 02 se trouve dans les deux tables...

SELECT a.gid FROM table_a a, table_b b WHERE a.gid NOT IN (b.gid) ;

Je souhaiterais récupérer seulement les valeurs 01, 03, 04 et 05 qui sont bien dans la table_a mais pas dans la table_b.


Je ne vois vraiment pas ce qui cloche...



Merci pour votre aide !


Thomas

#45 Général » [RESOLU] Cumuler des lignes issues de tables distinctes » 12/11/2013 14:34:09

Thomas Williamson
Réponses : 2

Bonjour,


Pour résumer, je dispose de tables ayant exactement la même structure, soit par exemple :


- table_a (gid, date, type)
- table_b (gid, date, type)
- table_c (gid, date, type)


Je souhaiterais cumuler les lignes de ces tables en une seule avec une requête SQL. Je n'arrive pas à obtenir ce résultat car il faut nommer les colonnes de chaque table et le résultat obtenu cumule alors les colonnes de chaque table dans un grand tableau (soit de 9 colonnes si je reprends l'exemple ci-dessus).


Merci d'avance pour votre aide !


Thomas

#47 Général » Sélectionner une série discontinue de valeurs dans une colonne » 08/11/2013 10:24:51

Thomas Williamson
Réponses : 2

Bonjour,


Existe-t-il un moyen d'écrire plus simplement le type de requête suivante :


SELECT * FROM table WHERE gid = 125 OR gid = 145 OR gid = 236 OR gid = 111 OR... ;

En dehors des opérateurs de comparaisons (<, >, BETWEEN, etc.) qui permettent de gérer des séries continues de valeurs, existe-t-il une solution pour des séries discontinues comme dans l'exemple ci-dessus ?



Merci pour vos avis !


Thomas

#48 Re : Général » [RESOLU] Requête avec count() dans plusieurs tables » 06/11/2013 12:26:29

Parfait avec la clause DISTINCT ! Je récupère bien les chiffres voulus. Par contre, après avoir regardé la doc sur ce sujet, je ne comprends pas l'utilisation de DISTINCT sur un gid (clé primaire) car cette colonne est sensée stocker des valeurs uniques... Ça doit tenir au fait que j'interroge plusieurs tables , non ?

#49 Général » [RESOLU] Requête avec count() dans plusieurs tables » 06/11/2013 10:55:50

Thomas Williamson
Réponses : 3

Bonjour,


J'ai les tables suivantes :


- commune (gid, insee, nom)
- vanne (gid, type, date, insee)
- ventouse (gid, type, date, insee)


J'exécute la requête suivante pour comptabiliser le nombre de vannes et de ventouses par commune :


SELECT 
  a.insee AS commune, 
  count(b.gid) AS nb_vanne, 
  count(c.gid) AS nb_ventouse

FROM commune a
  LEFT JOIN vanne b ON a.insee = b.insee
  LEFT JOIN ventouse c ON a.insee = c.insee

WHERE a.insee = '86000'

GROUP BY a.insee ;

Le résultat de requête me donne 21840 vannes et 21840 ventouses alors que j'en ai en réalité respectivement 312 et 70... En effet, si je supprime l'un des deux count() et l'un des deux LEFT JOIN correspondant, j'obtiens le bon chiffre. Je ne vois pas trop d'où vient ce problème. Je précise que j'utilise la table commune pour pouvoir afficher l'ensemble des communes et non seulement celles référencées dans les tables vanne et ventouse.


Merci pour votre avis !


Thomas

#50 Re : Général » [RESOLU] Ajouter et remplir une colonne dans la même requête » 05/11/2013 16:02:34

Bonjour Arthurr,


C'est exactement ce que je cherchais à faire ! Désolé si je n'ai pas été clair... C'est la structure

'yes'::text as colonne3

qui me manquait.


Merci pour le dépannage !


Thomas

Pied de page des forums

Propulsé par FluxBB