Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2795 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [PG] Récupérer plusieurs fois plusieurs morceaux d'une table

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[PG] Récupérer plusieurs fois plusieurs morceaux d'une table

n°1637270
multani
Dépressionnisé
Posté le 06-11-2007 à 00:04:06  profilanswer
 

Salut ! [:dawa]
 
j'ai eu quelques problèmes à résoudre le problème suivant, et j'aurais voulu savoir si vous aviez de meilleurs idées ... [:dawa]
 
 
Voilà le problème :

  • j'ai une table 'villes', avec dedans, un colonne 'nom' de type text, et une colonne 'code_postal', de type text aussi. La table contient donc une liste de ville et le code postal associée à cette ville
  • j'aurais voulu récupérer pour chaque département, les X (premières) villes (disons, par ordre de code postal, mais c'est pas vraiment important)


Donc imaginons que j'ai l'équivalent de 90 départements dans ma base, si je veux récupérer les 10 premières villes de chaque département, je dois récupérer 900 couples ville/code_postal.
 
 
Question : comment je fais ?
 
 
J'ai essayé plusieurs trucs :

  • récupérer le code postal, facile. Mais j'arrive pas à en faire grand chose
  • faire des tests en prenant que deux départements. Ça donnait quelque chose dans ce gout là (attention les yeux) :
Code :
  1. SELECT commune, code_postal
  2. FROM (
  3.     SELECT nom, code_postal
  4.     FROM villes
  5.     WHERE code_postal LIKE '01%'
  6.     LIMIT 5
  7. ) AS t
  8.  
  9. UNION
  10.  
  11. SELECT commune, code_postal
  12. FROM
  13. (
  14.     SELECT nom, code_postal
  15.     FROM villes
  16.     WHERE code_postal LIKE '02%'
  17.     LIMIT 5
  18. ) AS t
  19.  
  20. ORDER BY code_postal


... mais bon, à part coller 90 fois ce code, pas terrible non plus.
 
Là, j'ai réussi à me démerder avec une procédure stockée, qui fait ce copier/coller (en fait). Ça génère une grosse requête, que j'exécute dans un curseur, puis je retourne le curseur et je fais un FETCH ALL dessus [:klem3i1].
Ça me semble un peu gorret [:dawa]
 
 
Donc voilà, est-ce que vous auriez une meilleure solution ?

mood
Publicité
Posté le 06-11-2007 à 00:04:06  profilanswer
 

n°1637837
multani
Dépressionnisé
Posté le 06-11-2007 à 21:00:57  profilanswer
 

Ya pas de roxorz du SQL par là ? [:dawak]

n°1637876
nxb
Posté le 06-11-2007 à 22:40:48  profilanswer
 

HFR c'est plus ce que c'était :o


---------------
"Hello IT ? Have you tried turning it off and on again ?"
n°1638374
MagicBuzz
Posté le 07-11-2007 à 15:48:06  profilanswer
 

grmpf.
 
je pars fumer une clope, si je me souvient de ton problème à mon retour, je regarde [:magicbuzz]

n°1638412
MagicBuzz
Posté le 07-11-2007 à 16:19:50  profilanswer
 

Voilà, inspire toi de ce petit test que je viens de faire :
 

Code :
  1. SELECT *
  2. FROM
  3. (
  4. SELECT tie.typtie, tie.sigtie,
  5. sum(1) over (partition BY tie.typtie ORDER BY tie.typtie, tie.sigtie rows unbounded preceding) AS incr
  6. FROM tie
  7. WHERE tie.codsoc = 2 -- c'est juste un filtre pour faire joli
  8. ORDER BY tie.typtie, tie.sigtie
  9. ) tmp
  10. WHERE tmp.incr <= 5 -- je veux les 5 premiers par groups de tie.typtie
  11. ORDER BY typtie, sigtie


 
Ici, c'est sous Oracle 10gR2.
Je ne garanti pas que ce soit transposable 100% de façon identique sous PostGreSQL.
 
Ceci dit, il s'agit uniquement de mots clés SQL-92, donc PostGreSQL respectant très bien cette norme, tu peux avoir bon espoir.

n°1638539
MagicBuzz
Posté le 07-11-2007 à 17:46:16  profilanswer
 

tu peux aussi essayer de te démerder avec la doc de T-SQL, puisque la syntaxe est différente (et là j'ai pas le temps de regarder comment ça marche avec sql server)
http://msdn2.microsoft.com/fr-fr/library/ms189461.aspx

n°1638640
multani
Dépressionnisé
Posté le 07-11-2007 à 20:14:31  profilanswer
 

Salut !
 
Merci d'avoir répondu :)
 
Bon, par contre, ça m'aide pas trop, puisque Postgres ne support pas les fonctions sur des fenêtres (le sum(1) OVER (...) ) :(
 
Ceci dit, je vois un peu comment tu faisais ça, je vais voir si je peux trouver un moyen de faire la même chose sans passer par ces fonctionnalités ...

n°1638645
MagicBuzz
Posté le 07-11-2007 à 20:22:43  profilanswer
 

Ben sinon, tu fais une PS qui te retourne sous forme de table les 10 première villes d'un département. En faisant un inner join dessus à partir des départements, c'est gagné.

n°1638656
multani
Dépressionnisé
Posté le 07-11-2007 à 20:55:50  profilanswer
 

Pas bête, c'était presque bon :(

 
Code :
  1. CREATE OR REPLACE FUNCTION city_by_dep(dep integer) RETURNS SETOF villes AS $$
  2. DECLARE
  3.     line RECORD;
  4. BEGIN
  5.     FOR line IN SELECT * FROM villes WHERE code_postal LIKE dep || '%' ORDER BY code_postal LIMIT 10 LOOP
  6.         RETURN next line;
  7.     END LOOP;
  8.     RETURN;
  9. END;
  10. $$ LANGUAGE plpgsql;
 

et :

Code :
  1. SELECT *
  2. FROM (
  3.     SELECT substring(code_postal FOR 2) AS dep FROM villes GROUP BY dep ORDER BY dep
  4. ) AS t
  5. JOIN city_by_dep(t.dep) ON true


mais bon, apparement, j'ai pas le droit d'utiliser "t.dep" dans l'appel à la procédure :/


Message édité par multani le 08-11-2007 à 00:19:22
n°1638657
multani
Dépressionnisé
Posté le 07-11-2007 à 20:56:36  profilanswer
 

Bon, ceci dit, ça m'a permis du coup de comprendre comment on pouvait récupérer plusieurs lignes à partir d'un appel à une procédure [:dawa]

mood
Publicité
Posté le 07-11-2007 à 20:56:36  profilanswer
 

n°1638686
MagicBuzz
Posté le 08-11-2007 à 00:10:08  profilanswer
 

c'est exprès la faute de frappe dans la ligne 5 de ta fonction ?
 
parceque sinon, mise à part limitation praticulière de PG, et syntaxe mise à part (je maîtrise plutôt le T-SQL qui diffère énormément), le principe me semble tout à fait bon.
 
je vérifierai demain, mais il me semble que j'utilise justement ce système au boulot (pour une toute autre raison) et ça passe sans problème sous sql server. ce serait bien con que ça ne passe pas sous pg :/

n°1638689
multani
Dépressionnisé
Posté le 08-11-2007 à 00:22:15  profilanswer
 

MagicBuzz a écrit :

c'est exprès la faute de frappe dans la ligne 5 de ta fonction ?


oups, en passant les mots clés en majuscule, j'ai oublié un E :p
 

MagicBuzz a écrit :

parceque sinon, mise à part limitation praticulière de PG, et syntaxe mise à part (je maîtrise plutôt le T-SQL qui diffère énormément), le principe me semble tout à fait bon.
 
je vérifierai demain, mais il me semble que j'utilise justement ce système au boulot (pour une toute autre raison) et ça passe sans problème sous sql server. ce serait bien con que ça ne passe pas sous pg :/


Bon, après, comme j'ai dis, j'ai découvert tout à l'heure comment utiliser une fonction pour récupérer plusieurs résultats, donc chuis ptêtre pas forcément super au point non plus.
 
Je poserais la question sur la ML postgresql-user pour voir si quelqu'un connaissant bien Postgres a une meilleure solution.
 
 
Merci :hello:

n°1638913
MagicBuzz
Posté le 08-11-2007 à 11:37:34  profilanswer
 

Bon, j'ai fait mumuse tout à l'heure, et je me suis rendu compte que... sous SQL Server non plus on peut pas faire de jointure sur une fonction de ce genre... du moins les paramètres attendus ne peuvent pas provenir des autres tables.
 
Bref.
 
Voici un script complet qui marche chez moi :
 

Code :
  1. DROP FUNCTION Get10ComPerDep;
  2. DROP TABLE com;
  3. DROP TABLE dep;
  4.  
  5. CREATE TABLE dep
  6. (
  7.  nomdep char(23) NOT NULL PRIMARY KEY,
  8.  numdep char(2) NOT NULL
  9. );
  10. CREATE TABLE com
  11. (
  12.  insee char(5) NOT NULL PRIMARY KEY,
  13.  codpos char(5) NOT NULL,
  14.  nomcom char(26) NOT NULL,
  15.  nomdep char(23) NOT NULL REFERENCES dep(nomdep)
  16. );
  17.  
  18. CREATE INDEX ix_nomcom ON com (nomcom);
  19. CREATE INDEX ix_codpos ON com (codpos);
  20. go
  21.  
  22. CREATE FUNCTION Get10ComPerDep()
  23. returns @ret TABLE
  24. (
  25.  nomdep char(23),
  26.  codpos char(5),
  27.  nomcom char(26),
  28.  insee char(5) PRIMARY KEY
  29. )
  30. AS
  31. begin
  32.  declare @nomdep char(23);
  33.  
  34.  declare curdep cursor FOR
  35.  SELECT nomdep FROM dep;
  36.  
  37.  open curdep;
  38.  
  39.  fetch next FROM curdep INTO @nomdep;
  40.  
  41.  while @@fetch_status = 0
  42.  begin
  43.    INSERT INTO @ret (nomdep, codpos, nomcom, insee)
  44.    SELECT top 10 @nomdep, codpos, nomcom, insee FROM com WHERE nomdep = @nomdep ORDER BY codpos;
  45.  
  46.    fetch next FROM curdep INTO @nomdep;
  47.  end;
  48.  
  49.  close curdep;
  50.  deallocate curdep;
  51.  
  52.  RETURN;
  53. end;
  54. go
  55.  
  56. INSERT INTO dep (nomdep, numdep)
  57. SELECT DISTINCT departement, LEFT(codepos, 2)
  58. FROM insee
  59. ORDER BY 1;
  60.  
  61. INSERT INTO com (insee, codpos, nomcom, nomdep)
  62. SELECT insee, codepos, commune, departement
  63. FROM insee
  64. ORDER BY 1;
  65.  
  66. SELECT *
  67. FROM Get10ComPerDep()
  68. ORDER BY nomdep, nomcom;


 
(bon, au début je me prends la tête pour recopier "proprement" une table "INSEE" récupérée sur le net dans deux tables "com" et "dep", n'y prête pas attention ;))

n°1638928
multani
Dépressionnisé
Posté le 08-11-2007 à 11:50:54  profilanswer
 

Ouais, j'avais pensé à faire un truc comme ça au début en fait ...
... sauf que je savais pas retourner plusieurs lignes d'un coup :D
 
D'où ma première "solution"  [:petrus75]
 
Donc là, ouais, en faisant une boucle sur les départements, puis une requête pour récupérer 10 villes et RETURN NEXT sur le résultat, c'est cool [:romf]


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [PG] Récupérer plusieurs fois plusieurs morceaux d'une table

 

Sujets relatifs
Récupérer valeur d'une clé de registreRequête récuperer x enregistrement tableau
Récuperer la valeur d'un typre radiorecupere automatiquement des données d une table MySQL dans un forulai
Récupérer les données d une table dans un formulaireAffichages plusieurs images
Cherche un outil simple d'édition de tableRecuperer des valeurs dans un fichier xls.
verifier plusieurs champs d'un formulaire dans une meme fonction 
Plus de sujets relatifs à : [PG] Récupérer plusieurs fois plusieurs morceaux d'une table


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR