开发者

SQL joins query not acting as wanted

I have the following tables:

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,
PRI开发者_Python百科MARY KEY (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

I want to select all the members that have not attended the two latest talks. The query I have written looks like this:

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;

Is this correct? Or have I not understood joins correctly?


A somewhat horrible approach, I fear - but one that should work...

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


Pretty much exactly like you would say it in English

   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)

NOTE: The subquery:

 (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)

returns the list of members who attended the talks which have 2 or fewer subsequent talks

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜