Oracle : Restriction sur une requete - SQL/NoSQL - Programmation
Marsh Posté le 13-01-2012 à 12:16:33
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?
Marsh Posté le 13-01-2012 à 14:32:24
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 ?
Marsh Posté le 13-01-2012 à 14:37:11
Oui, c'est plus clair...mais plus compliqué à faire!
Il peut y avoir plusieurs fois la même lésion sur une demande?
Marsh Posté le 13-01-2012 à 15:08:19
c'est bien pour ça que je galère
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.
Marsh Posté le 13-01-2012 à 15:14:39
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?
Marsh Posté le 13-01-2012 à 15:30:07
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...
Marsh Posté le 13-01-2012 à 15:35:05
Excellente remarque.
Dans ce style alors?
Code :
|
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...
Marsh Posté le 13-01-2012 à 15:58:56
La jointure externe me semble une bonne idée, j'ai tenté mais c'est pas encore ça :
Code :
|
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)
Marsh Posté le 13-01-2012 à 16:05:31
Tu as oublié ad2.nudde is null dans le where, si je ne bigle pas.
Marsh Posté le 13-01-2012 à 16:43:58
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
Marsh Posté le 13-01-2012 à 16:47:45
ah ouais, ça fonctionne bien avec
Il sert à quoi ? (juste pour ma culture g )
Marsh Posté le 13-01-2012 à 16:48:52
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.
Marsh Posté le 13-01-2012 à 17:02:00
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).
Marsh Posté le 13-01-2012 à 17:03:47
Une autre façon de faire serait celle-ci :
Code :
|
Marsh Posté le 13-01-2012 à 17:04:03
...enfin là il manque le compte, mais tu vois l'idée...
Marsh Posté le 13-01-2012 à 17:28:13
KevinTran 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) ...
Marsh Posté le 13-01-2012 à 17:35:34
robbyone a écrit : |
c'est bien trop lourd à mettre en place...
Marsh Posté le 13-01-2012 à 17:39:24
ReplyMarsh Posté le 24-01-2012 à 12:10:03
KevinTran a écrit : Merci beaucoup |
Et les opérateurs ensemblistes ?
Code :
|
Avec un with, pas d'impact sur les perfs et la syntaxe serais plus simple (en principe).
Marsh Posté le 24-01-2012 à 13:52:29
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à.
Marsh Posté le 24-01-2012 à 14:05:54
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.
Marsh Posté le 13-01-2012 à 11:29:30
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