SQL连接查询不按预期行事

时间:2010-08-15 20:57:02

标签: sql mysql database

我有以下表格:

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; 

我想选择所有未参加过两次最新会谈的成员。我写的查询看起来像这样:

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;

这是对的吗?或者我没有正确理解连接? 在此先感谢,
迪恩

2 个答案:

答案 0 :(得分:1)

一种有点可怕的方法,我担心 - 但应该有效......

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

答案 1 :(得分:1)

非常像你用英语说的那样

   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)

注意:子查询:

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

返回参加会谈的成员名单,其中有2次或更少的后续会谈