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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Requète impossible à faire simplement?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Requète impossible à faire simplement?

n°578304
gizmo
Posté le 28-11-2003 à 14:35:00  profilanswer
 

Supposons les tables triviales A et B suivantes:
 
A
_
1
1
1
2
2
 
B
_
1
2
 
Maintenant, je voudrais arriver à retirer de A les élément de B le nombre de fois qu'ils sont présents dans B, ce qui me donnerait au final
 
A
_
1
1
2
 
Pour obtenir ce résultat dans une sélection, pas de problème, ca passe sans problème avec un except, mais je ne vois pas le moyen simple de le faire pour un delete. Et je ne peux pas me permettre de faire une copie de la table que je renommerais par la suite.
 
quelqu'un aurait-il une idée? En PgSQL, et si possible en restant dans le SQL standard (mais c'est pas obligé).

mood
Publicité
Posté le 28-11-2003 à 14:35:00  profilanswer
 

n°578337
Mara's dad
Yes I can !
Posté le 28-11-2003 à 15:43:28  profilanswer
 

Est-ce que tu peut ajouter (temporairement) des colonnes à A et à B ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578340
gizmo
Posté le 28-11-2003 à 15:46:26  profilanswer
 

J'y ai pensé. rajouter une colonne avec un compteur mais c'est assez lourd. Je cherchais, si possible une solution plus légère.

n°578343
Mara's dad
Yes I can !
Posté le 28-11-2003 à 15:49:29  profilanswer
 

Idée :
 
Je nome X, la colonne qui contient les données dont tu parles.
 
1- Ajouter un champ ID dans A et dans B.
2- Dans A, l'ID vas de 1 à N c'est en gros un N° d'enregistrement
3- Dans B, update B set ID = (select A.ID from A where A.X = B.X and A.ID=min(A.ID) )
4- delete A where ID in ( select ID from B )
5- Supprimer les champs ID dans A et B


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578391
MagicBuzz
Posté le 28-11-2003 à 16:25:36  profilanswer
 

C'est merdique ton truc.
 
Est-ce que ta base de données permet de bosser avec le RowID ?
 
Si oui, alors pas besoin d'ajouter un identifiant, il y est déjà, c'est le rowid.

n°578402
Mara's dad
Yes I can !
Posté le 28-11-2003 à 16:28:30  profilanswer
 

Y fait comme y veux hein.
Mais pour son problème, ben je vois pas grand chose d'autre (dans le principe général) s'il ne peut pas recopier dans une autre table.


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578403
MagicBuzz
Posté le 28-11-2003 à 16:28:49  profilanswer
 

Sinon, je vois pas comment c'est possible en SQL Standard, à moins de passer par du PL/SQL ou T-SQL.
 
Je verrais un truc bourrin comme ça :
 

delete A where rowid in (select top (select count(col) from B group by B.col) rowid
from A
where A.col = B.col)


 
Mais je doute que cette requête marche (j'ai pas de sql server sous la main, et avec oracle y'a pas de "top" )

n°578406
MagicBuzz
Posté le 28-11-2003 à 16:33:24  profilanswer
 

c'est tout faux mon truc. Mais y'a de l'idée. Chuis en train de voir comment la refaire sous Oracle

n°578408
MagicBuzz
Posté le 28-11-2003 à 16:38:51  profilanswer
 

Mmm... En fait mon truc est pas possible, il faudrait pouvoir faire un group by sur le top, et c'est pas possible à ma connaissance...

n°578421
Mara's dad
Yes I can !
Posté le 28-11-2003 à 16:48:00  profilanswer
 

Je l'ai :
 

Code :
  1. delete from A
  2. where
  3. rowid in
  4.  select
  5.   x_row
  6.  from
  7.  (
  8.   select
  9.    a.col,
  10.    min( A.rowid ) x_row
  11.   from
  12.    A,
  13.    B
  14.   where
  15.    A.col = B.col
  16.   group by
  17.    a.col
  18.  )
  19. )


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
mood
Publicité
Posté le 28-11-2003 à 16:48:00  profilanswer
 

n°578424
Mara's dad
Yes I can !
Posté le 28-11-2003 à 16:49:28  profilanswer
 

M'enfin c'est pour Oracle, (testé et approuvé ), reste à l'adapter à postgres.
Y'a des rowid dans postgres ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578428
MagicBuzz
Posté le 28-11-2003 à 16:51:23  profilanswer
 

elle est bizarre ta requête.  
 


     select
      a.col,
      min( A.rowid ) x_row
     from
      A,
      B
     where
      A.col = B.col
     group by
      a.col


 
Ca fait quoi au juste ça ? (peut pas trop jouer sur le serveur ici, c'est la base de l'ERP et ça ferait chier les gens si je virait des commandes et des clients pour tester :D)

n°578430
gizmo
Posté le 28-11-2003 à 16:52:24  profilanswer
 

ok, merci pour vos efforts...mais:
 
- pour le moment, je ne connais aucun moyen d'accéder aux rowid dans postgres. J'ai beau chercher dans la doc, je ne vois rien (j'ai essayé rowid et row_id sans sucès) :/
 
- la solution de Mara's dad fonctionnera effectivement si je n'ai que des valeurs uniques dans B. Mon problème, que j'ai oulié de précisé (mea culpa) c'est que je pourrais très bien avoir un B comme ça:
B
_
1
1
2
 
voila voila

n°578455
Mara's dad
Yes I can !
Posté le 28-11-2003 à 17:01:55  profilanswer
 

MagicBuzz :
 
quand je fais
 
where toto in (...)
 
ce qu'il y a dans (...) ne doit retourner qu'un seul champs.
 
Or pour faire la sélection de ce qu'on veux, il faut faire :
 
select un_champs, min(rowid), from table group by un_champs.
 
ce qui retourne 2 champs !
 
Donc je donne un alias à min(rowid) et j'encapsule le tout dans une autre requête :
 
select x_row from (...)  
 
C'est une astuce que j'ai déjà utilisé, mais çà fait au moins 3 niveaux d'imbrication !
 
gizmo:
T'est chiant  :D


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578458
gizmo
Posté le 28-11-2003 à 17:03:39  profilanswer
 

je sais [:ddr555]

n°578460
Mara's dad
Yes I can !
Posté le 28-11-2003 à 17:04:05  profilanswer
 

gizmo :
T'as pas un identifiant unique dans A pour remplacer le rowid ?
 
Pour le reste, je cherche...


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578464
MagicBuzz
Posté le 28-11-2003 à 17:07:49  profilanswer
 

Mara's dad a écrit :

MagicBuzz :
 
quand je fais
 
where toto in (...)
 
ce qu'il y a dans (...) ne doit retourner qu'un seul champs.
 
Or pour faire la sélection de ce qu'on veux, il faut faire :
 
select un_champs, min(rowid), from table group by un_champs.
 
ce qui retourne 2 champs !
 
Donc je donne un alias à min(rowid) et j'encapsule le tout dans une autre requête :
 
select x_row from (...)  
 
C'est une astuce que j'ai déjà utilisé, mais çà fait au moins 3 niveaux d'imbrication !
 
gizmo:
T'est chiant  :D  


ça j'avais bien compris ;)
c'est le premier truc que j'ai corrigé dans ma requête quand j'ai commencé à jouer avec :D
 
mais je vois pas où tu "retirer de A les élément de B le nombre de fois qu'ils sont présents dans B"

n°578465
MagicBuzz
Posté le 28-11-2003 à 17:08:31  profilanswer
 

ha ! je crois que je viens d'avoir une illumination.
 
nan, ct pas une apparition de la vierge, c'est juste que je viens de tilter. j'ai compris la requête  ;)
 
chapeau :jap:

n°578471
Mara's dad
Yes I can !
Posté le 28-11-2003 à 17:12:37  profilanswer
 

L'identifiant de record dans postgres, c'est OID !
 
http://www.postgresql.org/docs/7.4 [...] lumns.html


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578527
Mara's dad
Yes I can !
Posté le 28-11-2003 à 18:03:36  profilanswer
 

Appelez moi DIEU !
 
delete from "A" where "A".OID in ( select "A".OID from "A" where "A".col || '_' || ( select count(*) from "A" as a1 where a1.OID <= "A".OID AND a1.col="A".col ) in ( select "B".cal || '_' || ( select count(*) from "B" as b1 where b1.OID <= "B".OID AND b1.col="B".col ) from "B" ) );
 
 :sol:  :sol:  :sol:


Message édité par Mara's dad le 28-11-2003 à 22:59:43

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578528
gizmo
Posté le 28-11-2003 à 18:05:33  profilanswer
 

[:prosterne][:prosterne][:prosterne]
[:prosterne][:prosterne][:prosterne]
[:prosterne][:prosterne][:prosterne]
 
:jap::jap::jap:
:jap::jap::jap:
:jap::jap::jap:

n°578531
Mara's dad
Yes I can !
Posté le 28-11-2003 à 18:09:42  profilanswer
 

J'ai rarement vu un truc aussi capilotracté :lol:


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578532
simogeo
j'ai jamais tué de chats, ...
Posté le 28-11-2003 à 18:12:07  profilanswer
 

Mara's dad a écrit :

Appelez moi DIEUX !
 
delete from "A" where "A".OID in ( select "A".OID from "A" where "A".col || '_' || ( select count(*) from "A" as a1 where a1.OID <= "A".OID AND a1.col="A".col ) in ( select "B".cal || '_' || ( select count(*) from "B" as b1 where b1.OID <= "B".OID AND b1.col="B".col ) from "B" ) );
 
 :sol:  :sol:  :sol:  



note pour plus tard : Mara's dad sait faire des requêtes incompréhensible et qui marche
:whistle:


---------------
from here and there -- \o__________________________________ -- la révolution de la terre, en silence
n°578534
Mara's dad
Yes I can !
Posté le 28-11-2003 à 18:13:57  profilanswer
 

simogeo a écrit :



note pour plus tard : Mara's dad sait faire des requêtes incompréhensible et qui marche
:whistle:  


 
Comment çà incompréhensible ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578535
simogeo
j'ai jamais tué de chats, ...
Posté le 28-11-2003 à 18:17:21  profilanswer
 

Mara's dad a écrit :


 
Comment çà incompréhensible ?


dans le sens ou j'ai rien capté  :D  .... j'ai pas essayé de capter non plus  ;)  ... mais rien que la syntaxe m'effraie [:totoz]
 
bien joué, quoi [:bien]
 
edit : viens de regarder, et ca n'a pas l'air si compliqué que ca en fait mais bon, c'est bien quand même  :o  :D


Message édité par simogeo le 28-11-2003 à 18:18:35

---------------
from here and there -- \o__________________________________ -- la révolution de la terre, en silence
n°578545
Mara's dad
Yes I can !
Posté le 28-11-2003 à 18:25:31  profilanswer
 

OID, c'est un identifiant numérique unique de postgres, donc :
 
select col, ( count(*) from A as a1 where a1.OID <= A.OID AND a1.col=A.col ) FROM A
Donne :
1 1
1 2
1 3
2 1
2 2
 
En clair, pour chaque valeur de col, je compte combien de records de la table on la même valeur de col et un OID plus petit.
 
Je fait pareil pour B :
1 1
1 2
2 1
 
Ensuite je concatène les champs avec un _ entre les deux (pour chaque table) :
pour A:
1_1
1_2
1_3
2_1
2_2
 
Pour B:
1_1
1_2
2_1
 
On a alors la liste des pseudo valeurs à supprimer, reste à tout mettre ensemble :
 
delete from A where OID in ( select OID from A where CONCATENATION_DE_COL_ET_DU_COMPTEUR_DE_A in ( SELECT CONCATENATION_DE_COL_ET_DU_COMPTEUR_DE_B from B ) );
 
 
Faut juste prendre le problème dans le bon sens :D


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578550
SomeBugsIn​Me
life suxx
Posté le 28-11-2003 à 18:35:59  profilanswer
 


 
Bah comme ça moi j'apprends des trucs  :)

n°578551
the real m​oins moins
Posté le 28-11-2003 à 18:37:09  profilanswer
 

et si tu faisais la selection dans ton appli, "betement" ? [:spamafote]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°578702
gizmo
Posté le 28-11-2003 à 22:36:21  profilanswer
 

the real moins moins a écrit :

et si tu faisais la selection dans ton appli, "betement" ? [:spamafote]


gni?

n°578736
simogeo
j'ai jamais tué de chats, ...
Posté le 28-11-2003 à 23:09:56  profilanswer
 

the real moins moins a écrit :

et si tu faisais la selection dans ton appli, "betement" ? [:spamafote]


[:newidk]


---------------
from here and there -- \o__________________________________ -- la révolution de la terre, en silence
n°578738
MagicBuzz
Posté le 28-11-2003 à 23:10:10  profilanswer
 

il veut dire dans le programme qui appelle la requête sql plutôt que directement dans la requête

n°578743
Mara's dad
Yes I can !
Posté le 28-11-2003 à 23:12:09  profilanswer
 

Dans le prog, pourquoi pas !
 
T'as un algo simple pour faire çà MagicBuzz ?
 
Plus simple qu'une requête qui fait tout en une fois ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578758
gizmo
Posté le 28-11-2003 à 23:21:07  profilanswer
 

ah! ok. Bah non, ça ne m'est pas possible. le programme qui demande la suppression ne travaille pas directement sur la DB mais au travers d'un wrapper, le schema de la DB étant censé pourvoir bouger dans le temps sans que l'appli n'aie à être remodifiée.

n°578813
MagicBuzz
Posté le 28-11-2003 à 23:51:14  profilanswer
 

Mara's dad a écrit :

Dans le prog, pourquoi pas !
 
T'as un algo simple pour faire çà MagicBuzz ?
 
Plus simple qu'une requête qui fait tout en une fois ?


y'a toujours le problème du rowid.
 
sans le rowid, je vois pas comment faire...
 
sinon, c'est simple en prog...
 
"select distinct A from T1"
while (canRead)
{
    "select count(A) from T2 where A = " + sqlA
    "delete T1 where rowID in (select top " + sqB + " from T1 where A = " + sqA + " )"
    moveNext
}

n°578819
Mara's dad
Yes I can !
Posté le 28-11-2003 à 23:57:22  profilanswer
 

T'as pas tou lu toi !
 
En postgres, y'a le OID qui fait la même chose que le rowid.
 
J'ai rien capté à ton algo...
En quoi il est plus simple que ma requête magique ?
 
Et puis faire des delete dans une boucle sur la même table, c'est jamais très safe . . .


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°578852
MagicBuzz
Posté le 29-11-2003 à 01:27:18  profilanswer
 

1) en quoi j'ai pas tout lu ? je retire bien de A les éléments de B le nombre de fois qu'ils sont présents dans B :heink:
 
2) j'avais pas fait gaffe à ce post en effet.
 
3) il est pas plus compliqué que ta requête. j'ai jamais dit qu'il était plus simple, il est par contre plus trivial.
 
4) je vois pas en quoi c'est gênant de faire un delete dans une boucle...

n°578872
Mara's dad
Yes I can !
Posté le 29-11-2003 à 10:06:51  profilanswer
 

1,2- Je dis que t'as pas tout lu quand tu parles du problème du rowid :D
En postgres, y'a OID qui remplace.
 
3- Je viens de comprendre comment tu fait ton delete. OK, sauf que en postgres, c'est pas top, mais LIMIT.
 
4- Les deletes dans une boucle (sur la table elle même, et seulement dans ce cas) poser des problèmes avec certains SGBD.
 
---------------------------------------
 
Et puis merde, je suis désapointé parce-que tu t'es pas extasié devant ma super requête super géniale et tout :o


Message édité par Mara's dad le 29-11-2003 à 10:12:36

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°579943
MagicBuzz
Posté le 01-12-2003 à 00:59:30  profilanswer
 

Mara's dad a écrit :

1,2- Je dis que t'as pas tout lu quand tu parles du problème du rowid :D
En postgres, y'a OID qui remplace.
 
3- Je viens de comprendre comment tu fait ton delete. OK, sauf que en postgres, c'est pas top, mais LIMIT.
 
4- Les deletes dans une boucle (sur la table elle même, et seulement dans ce cas) poser des problèmes avec certains SGBD.
 
---------------------------------------
 
Et puis merde, je suis désapointé parce-que tu t'es pas extasié devant ma super requête super géniale et tout :o


4) bah à priori, si tu fait une transaction pour le tout, du devrait pouvoir pallier aux éventuels problèmes de lock engendrés pas une série de delete de suite (seule problème éventuel que je vois)
 
-----------
 
Sisi, elle est très jolie ta requête, un peu mac giver sur les bords, mais tout à fait bien :D

mood
Publicité
Posté le   profilanswer
 


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

  Requète impossible à faire simplement?

 

Sujets relatifs
sql requete aide pleaseRequete NOT IN
aider mon pour ma requete Sql svp[VBA/ADO] Impossible de choisir une valeur ds ma combo
probleme avec une requete de type update en ASPrequete SQL lister les users d'un groupe
Problème requêteProbleme requete
afficher le nombre de requete et le temp de chargementEquivalent SQL Server d'une simple Requete Access
Plus de sujets relatifs à : Requète impossible à faire simplement?


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