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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Oracle : Restriction sur une requete

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Oracle : Restriction sur une requete

n°2121151
KevinTran
Photographe
Posté le 13-01-2012 à 11:29:30  profilanswer
 

J'ai une base Oracle contenant plusieurs milliers de références et je fais une recherche sur quelques champs :
 
nudemande | nupatient | lesion
(int)          | (int)        | (txt)
 
Je veux sélectionner les demandes qui ont une lesion de type "UR0700 ET UR 7700", donc si je fais un :
"and lesion in ('UR0700', 'UR7700')"
ça me sort bien les demandes qui ont ces deux lésions...
 
MAIS, cette demande en question peut avoir une troisième, voire 4ème lésion :
(exemple sorti avec 3 lésions)
 
1748494 | 1835519 | UR0713
1748494 | 1835519 | 7700
1748494 | 1835519 | UR0700
 
Comment faire pour filtrer dans une seule requête, les demandes qui ont ces lésions présentes et uniquement ces deux là... (pas une seule, ni les 2 + 1 différente, etc).
J'imagine qu'il faudrait pouvoir imbriquer deux requêtes mais j'ai du mal à voir comment.
 
Je pensais à une première requête qui me sorte la liste des n° de demande, et après je fais une vérification pour voir si ces n° de demande contiennent bien 2 lésions et seulement 2...


---------------
http://www.kevintran.fr
mood
Publicité
Posté le 13-01-2012 à 11:29:30  profilanswer
 

n°2121167
skeye
Posté le 13-01-2012 à 12:16:33  profilanswer
 

C'est pas clair. Ton premier exemple ne fait pas ce que tu demandes dans la suite...
Il te faut quoi, les demandes qui ont exactement les lésions spécifiées?


---------------
Can't buy what I want because it's free -
n°2121179
KevinTran
Photographe
Posté le 13-01-2012 à 14:32:24  profilanswer
 

Ah oui effectivement, mon exemple porte sur :
1) lésions ayant comme n° de demande '1748394' (pour vérifier le nombre de lésions = en l'occurence, 3, la UR0713 est en trop)
 
2) La requête portant sur les 2 lésions que je cherche (version simplifiée) :
select *
from demande, codelesion
where codelesion in ('7700','UR0700')
 
Mais avec cette requête (2), je peux avoir un patient qui a 5 lésions dont les 2 que je cherche, alors que ce que je souhaite ce sont les patients n'ayant QUE les 2 lésions recherchées (aucune autre et pas une seule...)
 
ça semble plus clair ? [:cerveau quest]


---------------
http://www.kevintran.fr
n°2121181
skeye
Posté le 13-01-2012 à 14:37:11  profilanswer
 

Oui, c'est plus clair...mais plus compliqué à faire! :D
Il peut y avoir plusieurs fois la même lésion sur une demande?


---------------
Can't buy what I want because it's free -
n°2121185
KevinTran
Photographe
Posté le 13-01-2012 à 15:08:19  profilanswer
 

c'est bien pour ça que je galère :D
On part du principe qu'il n'y a qu'une fois la même lésion sur une demande :)
 
Dans l'idée, je partais sur une combinaison de requêtes :
 
select numdemande, etc
from tables...
where numdemande in (
select unique (demande)
from tables...
where lesion in ('bla')
)
...
 
et là je bloque...
 
J'aurai voulu faire une liste des demandes contenant les 2 lésions (ou plus), et à partir de cette liste de demande, vérifier le nombre de lésions totales par demande (si =2 alors il n'y a bien que ces 2 lésions). Si je peux avoir une correspondance :
numdem | nombrelesions
ce serait déjà pas mal.


---------------
http://www.kevintran.fr
n°2121186
skeye
Posté le 13-01-2012 à 15:14:39  profilanswer
 

Ce genre de choses doit pouvoir marcher, à défaut d'être joli?
 
select numdemande, count(*)
from tables
where lesion in (1,2,3,4)
group by numdemande
having count(*) = 4;
 
Pour chaque demande on compte le nombre de lésions qui font partie de la liste qu'on cherche, et on ne garde que celles qui ont le nombre exact?


---------------
Can't buy what I want because it's free -
n°2121187
KevinTran
Photographe
Posté le 13-01-2012 à 15:30:07  profilanswer
 

Oui pour ta dernière question, par contre la requête ne fonctionne pas...
 
En fait, ils vont tous sortir "2".
Le having count va se baser sur les résultats liés à la condition "lesion in ('','')", et cette condition renvoie bien 2 résultats, mais cela ne veut pas dire que la demande n'en a pas 3 ou 4...


---------------
http://www.kevintran.fr
n°2121189
skeye
Posté le 13-01-2012 à 15:35:05  profilanswer
 

Excellente remarque.:D
Dans ce style alors?

 
Code :
  1. SELECT t1.numdemande, count(*)
  2. FROM TABLE t1
  3.      LEFT OUTER JOIN TABLE t2 ON t1.numdemande = t2.numdemande AND t1.lesion IN (1,2,3,4) AND t2.lesion NOT IN (1,2,3,4)
  4. WHERE t2.numdemande IS NULL
  5. GROUP BY t1.numdemande
  6. HAVING count(*) = 4;
 

Idem qu'avant sauf qu'on fait une auto-jointure externe pour pouvoir sortir ceux qui ont des lesions en-dehors de la liste voulue...:D


Message édité par skeye le 13-01-2012 à 15:37:09

---------------
Can't buy what I want because it's free -
n°2121196
KevinTran
Photographe
Posté le 13-01-2012 à 15:58:56  profilanswer
 

La jointure externe me semble une bonne idée, j'ai tenté mais c'est pas encore ça :
 

Code :
  1. select d.nuddeext, count(*)
  2. from demande d, examencodifadi ad1 left outer join examencodifadi ad2
  3.                                     on ad1.nudde = ad2.nudde
  4.                                     and ad1.lesion in ('UR0700', '7700')
  5.                                     and ad2.lesion not in ('UR0700', '7700')
  6. where d.nudde = ad1.nudde
  7. and   d.datenreg > TO_DATE('01012010','DDMMYYYY')
  8. and   d.datenreg < TO_DATE('31122011','DDMMYYYY')
  9. and   ad1.modprel = 'B'
  10. and   ad1.typtech = 'H'
  11. and   ad1.organe = 'UR'
  12. and   ad1.lesion in ('UR0700', '7700')
  13. group by d.nuddeext
  14. having count(*)=2;


 
J'ai encore des résultats qui ont 3 lésions, mais j'ai l'impression qu'on est pas loin ^^ (p'tre la formulation de ma jointure qui coince un peu)


---------------
http://www.kevintran.fr
n°2121197
skeye
Posté le 13-01-2012 à 16:05:31  profilanswer
 

Tu as oublié ad2.nudde is null dans le where, si je ne bigle pas.


---------------
Can't buy what I want because it's free -
mood
Publicité
Posté le 13-01-2012 à 16:05:31  profilanswer
 

n°2121214
robbyone
Non pas !
Posté le 13-01-2012 à 16:43:58  profilanswer
 

ou un truc du genre
 
select user, count(*)
from table
where user not in ( select user from table where lesion in (unwanted,list) )
group by user
having count(*)=2

n°2121219
KevinTran
Photographe
Posté le 13-01-2012 à 16:47:45  profilanswer
 

ah ouais, ça fonctionne bien avec :)
 
Il sert à quoi ? (juste pour ma culture g :) )


---------------
http://www.kevintran.fr
n°2121220
KevinTran
Photographe
Posté le 13-01-2012 à 16:48:52  profilanswer
 

robbyone a écrit :

lesion in (unwanted,list)


 
Le souci c'est que cette "unwanted list" est trop longue et trop complexe à retrouver, il y a beaucoup trop de possibilités/combinaisons.


---------------
http://www.kevintran.fr
n°2121223
skeye
Posté le 13-01-2012 à 17:02:00  profilanswer
 

KevinTran a écrit :

ah ouais, ça fonctionne bien avec :)

 

Il sert à quoi ? (juste pour ma culture g :) )

 

C'est une astuce toute bête pour remplacer des "not in"/"not exists" : une jointure externe avec un critère qu'on ne veut pas (ici, le lesion not in...), et ensuite on prend toutes les lignes pour lesquelles cette table ne retourne rien (donc null pour tous les champs de cette table).


Message édité par skeye le 13-01-2012 à 17:03:02

---------------
Can't buy what I want because it's free -
n°2121224
skeye
Posté le 13-01-2012 à 17:03:47  profilanswer
 

Une autre façon de faire serait celle-ci :

Code :
  1. SELECT ...
  2. FROM TABLE t1
  3. WHERE lesion IN (1,2,3,4)
  4. AND NOT EXISTS (SELECT 1 FROM TABLE t2 WHERE t1.id = t2.id AND t2.lesion NOT IN (1,2,3,4))


---------------
Can't buy what I want because it's free -
n°2121225
skeye
Posté le 13-01-2012 à 17:04:03  profilanswer
 

...enfin là il manque le compte, mais tu vois l'idée...


Message édité par skeye le 13-01-2012 à 17:04:09

---------------
Can't buy what I want because it's free -
n°2121234
robbyone
Non pas !
Posté le 13-01-2012 à 17:28:13  profilanswer
 

KevinTran a écrit :


 
Le souci c'est que cette "unwanted list" est trop longue et trop complexe à retrouver, il y a beaucoup trop de possibilités/combinaisons.


 
me semble que cette liste est constituée de toutes les lésions sauf les 2 que tu cherches ... => select * not on (1,2) ...

n°2121239
skeye
Posté le 13-01-2012 à 17:35:34  profilanswer
 

robbyone a écrit :


 
me semble que cette liste est constituée de toutes les lésions sauf les 2 que tu cherches ... => select * not on (1,2) ...


c'est bien trop lourd à mettre en place...


---------------
Can't buy what I want because it's free -
n°2121241
KevinTran
Photographe
Posté le 13-01-2012 à 17:39:24  profilanswer
 

Merci beaucoup :)


---------------
http://www.kevintran.fr
n°2123032
MEI
|DarthPingoo(tm)|
Posté le 24-01-2012 à 12:10:03  profilanswer
 

KevinTran a écrit :

Merci beaucoup :)


 
Et les opérateurs ensemblistes ?
 

Code :
  1. select
  2.     *
  3. from
  4.     TABLE
  5. where
  6.     COL in ('1', '2')
  7. minus
  8. select
  9.     *
  10. from
  11.    TABLE
  12. group by
  13.    ID
  14. having count(COL) > (select count(*) from TABLE where COL in ('1', '2'));


 
Avec un with, pas d'impact sur les perfs et la syntaxe serais plus simple (en principe).


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
n°2123041
KevinTran
Photographe
Posté le 24-01-2012 à 13:52:29  profilanswer
 

Intéressant, c'est possible de détailler un peu plus l'utilité du "minus" ?
 
J'ai vu par la suite (pour une autre requête) que je pouvais aussi utiliser une union, je ne sais pas si ça aurait marché dans ce cas là.


---------------
http://www.kevintran.fr
n°2123050
MEI
|DarthPingoo(tm)|
Posté le 24-01-2012 à 14:05:54  profilanswer
 

C'est la soustraction de deux ensemble :
- celui des lignes qui réponde aux lessions recherchées
- celui des lignes qui réponde aux lessions recherchées mais qui ont un nombre de lessions supérieur au nombre de lessions recherchées
 
Après c'est qu'une piste, car je ne pense pas que ma requete marche telle quelle.


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
mood
Publicité
Posté le   profilanswer
 


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

  Oracle : Restriction sur une requete

 

Sujets relatifs
tableau à double entrée à partir d'une requêterequete sql select... where... NOT in ...
Compter le nombre de résultats d'une requêteRequête moyenne visiteurs
Erreur d'écriture de fichier RMAN ORA-27040 OracleDates oracles justes à l'affichage mais fausses dans BD Oracle
[ORACLE] Remplacement de valeurs "NULL"[ORACLE] - génération d'ARCHIVE LOGS en masse
VBAccess Problème requête paramétrée FormulaireNoms de tables accentués sous Oracle
Plus de sujets relatifs à : Oracle : Restriction sur une requete


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