2009-09-21 7 views
0

J'ai une table appelée visite et une autre appelée mesure. La clé primaire sur Visit est vis_id et c'est aussi la clé étrangère dans la table Measurement. Maintenant, je voudrais écrire un rapport basé sur les données de la table de mesure sur les conditions suivantes:Comment écrire cela en SQL?

Visite a champ "itemAmount". Je veux seulement que les données dont itemAmount = 2 dans la table Visit et les deux lignes dans Measurement related to Visit aient une mesure1 et une mesure2 non nulles dans la table Measurement. Si l'un des deux a une valeur de mesure1 ou de mesure2 NULL, alors aucune des lignes ne doit être incluse.

Comment faire? Je sais comment joindre et comment écrire des conditions simples dans la clause where mais je n'ai aucune idée de comment tester cette "fonctionnalité de couple", c'est-à-dire tester que les deux lignes liées à Visit ont à la fois la mesure1 et la mesure2.

+0

J'ai écrit un peu incorrectement. Il y a une autre table: "Item" et celle-ci est liée à Visit thru vis_id. La mesure est alors liée à Item par Item_id qui est pk dans la table Item et fk dans la table Measurement. –

+0

mais le noyau de votre requête n'a pas besoin de tableau d'objet, n'est-ce pas? – van

Répondre

0

comme l'utilisation de la condition:

WHERE itemAmount = 2 
    AND measurement1 IS NOT NULL 
    AND measurement2 IS NOT NULL 

(si je vous ai bien compris)

+0

Merci pour votre réponse! Mais ce que j'essaie de faire est de tester que les deux lignes répondent à cette condition (que vous avez écrit ci-dessus). Je veux dire qu'il y a toujours deux rangées liées à une rangée dans la visite seulement si les deux répondent à la condition, alors les deux seront inclus. Sinon, soit l'une des lignes. –

0

En supposant que vos données d'échantillon est que vous avez spécifié:

Visit: 
vis_id  itemAmounts 
----------- ----------- 
1   2 
2   1 

Item: 
item_id  vis_id 
----------- ----------- 
1   1 
2   1 
3   2 

Measurement: 
item_id  measurement1 measurement2 
----------- ------------ ------------ 
1   10   20 
2   5   10 
3   5   5 

la requête doit être celle-ci:

select m1.* 
from Measurement m1 
join Item i1 
    on m1.item_id = i1.item_id 
join Visit v 
    on v.vis_id = i1.vis_id 
    and v.itemAmounts = 2 
join Item i2 
    on v.vis_id = i2.vis_id 
    and i1.item_id <> i2.item_id --//take the other item 
join Measurement m2 
    on i2.item_id = m2.item_id 
    and m2.Measurement1 IS NOT NULL 
    and m2.Measurement2 IS NOT NULL 
where m1.Measurement1 IS NOT NULL 
    and m1.Measurement2 IS NOT NULL 

ou celui-ci:

SELECT m1.* 
FROM Measurement m1 
JOIN Item i 
    ON m1.item_id = i.item_id 
JOIN (SELECT  v.vis_id 
     FROM  Visit v 
     INNER JOIN Item i 
       ON i.vis_id = v.vis_id 
     INNER JOIN Measurement m 
       ON m.item_id = i.item_id 
       AND m.Measurement1 IS NOT NULL 
       AND m.Measurement2 IS NOT NULL 
     WHERE  v.itemAmounts = 2 
     GROUP BY v.vis_id 
     HAVING  COUNT(*) = 2 
     ) v_filter 
    ON i.vis_id = v_filter.vis_id 

Les deux produisent le résultat suivant:

item_id  measurement1 measurement2 
----------- ------------ ------------ 
1   10   20 
2   5   10 

Est-ce ce que vous voulez?

+0

Merci, van! J'ai essayé ceci mais il ne retourne rien :(Si je supprime la ligne "et m1.ID <> m2.ID", il retourne deux lignes si les deux ont mes1 et mes2. Si l'un d'entre eux en a un nul, il renvoie toujours le autre: un conseil? :) PS J'ai ajouté la jointure à la table Item car c'est le seul moyen de référencer la table Visit pour vérifier le ItemAmount. –

+0

mais ce m1.ID <> m2.ID est très important. s'il vous plaît poster un échantillon des données, et la sortie attendue, car il est un peu pas clair ce que vous voulez exactement et ce qui ne fonctionne pas exactement – van

+0

@Micke: ajouté une autre option où la logique est de trouver toutes les visites pour lesquelles les mesures devraient s'affiche, puis affiche toutes les mesures correspondantes. – van

Questions connexes