2010-08-15 4 views
0

je les tableaux suivants:SQL se joint à la requête ne pas agir en voulait

CREATE TABLE `attendance_event_attendance` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`talk_id` varchar(200) NOT NULL, 
`membersAttended_id` varchar(200) NOT NULL, 
PRIMARY KEY (`id`), 
KEY `attendance_event_attendance_9ace4e5a` (`talk_id`), 
KEY `attendance_event_attendance_3c0dadb7` (`membersAttended_id`) 
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 

CREATE TABLE `attendance_member` (
`name` varchar(200) NOT NULL, 
`telephone_number` varchar(200) NOT NULL, 
`email_address` varchar(200) NOT NULL, 
`membership_type` varchar(1) NOT NULL, 
`membership_number` varchar(200) NOT NULL, 
PRIMARY KEY (`membership_number`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

CREATE TABLE `attendance_talk` (
`title` varchar(200) NOT NULL, 
`speaker` varchar(200) NOT NULL, 
`date_of_talk` date NOT NULL, 
PRIMARY KEY (`title`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

Je veux sélectionner tous les membres qui n'ont pas assisté aux deux derniers pourparlers. La requête que j'ai écrite ressemble à ceci:

SELECT m.name 
    from attendance_member as m 
left outer join attendance_event_attendance as ea on (ea.membersAttended_id=m.membership_number) 
join attendance_talk as t on (ea.talk_id = t.title) 
where t.date_of_talk >= 2010-06-01 
    AND ea.membersAttended_id = null; 

Est-ce correct? Ou ai-je pas compris joint correctement?
Merci à l'avance,
Dean

Répondre

1

Une approche quelque peu horrible, je crains - mais qui devrait fonctionner ...

SELECT m.name 
from attendance_member as m 
left outer join (
SELECT ea.membersAttended_id 
FROM attendance_event_attendance as ea 
join attendance_talk as t on (ea.talk_id = t.title) 
where t.date_of_talk >= 2010-06-01 
GROUP BY ea.membersAttended_id 
HAVING COUNT(*) = 2 
) attendingmembers 
ON attendingmembers.membersAttended_id = m.membership_number 
WHERE attendingmembers.membersAttended_id IS NULL 
+0

Merci. Je suppose que j'ai vraiment besoin de travailler sur mon SQL ... comme im faire plus de travail de base de données. – Dean

+0

@Dean - ce qui précède est très malade - la date + HAVING COUNT (*) = 2 est horrible, il y a de meilleurs moyens, introduire une autre sous-requête pour obtenir 'les deux dernières discussions' serait bien mieux que date_d_talk> une date. –

1

à peu près exactement comme vous le dire en anglais

Select Distinct m.name   -- Select names 
    From attendance_member M  -- of members 
     Where Not Exists   -- who did not attend the last two talks 
     (Select * From attendance_event_attendance a 
      Join attendance_talk t 
       On a.talk_id = t.title 
     Where a.membersAttended_id = m.membership_number 
      And (Select Count(*) From attendance_talk 
       Where date_of_talk >= t. date_of_talk) <= 2) 

REMARQUE: La sous-requête:

(Select * From attendance_event_attendance a 
    Join attendance_talk t 
     On a.talk_id = t.title 
    Where a.membersAttended_id = m.membership_number -- (correlated w/outer query) 
    And (Select Count(*) From attendance_talk 
      Where date_of_talk >= t. date_of_talk) <= 2) 

retourne la liste des membres qui ont assisté aux discussions qui ont eu 2 ou moins de discussions subséquentes