SQL присоединяется к запросу, не действующему как хотел

0

У меня есть следующие таблицы:

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;

Это правильно? Или я не понял правильно? Спасибо, Advance,
Дин

Теги:
database

2 ответа

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
  • 0
    Спасибо. Я думаю, мне действительно нужно работать над своим SQL ... так как я делаю больше работы с базой данных.
  • 0
    @Dean - вышесказанное довольно больное - дата + HAVING COUNT (*) = 2 ужасна, есть лучшие способы, введя другой подзапрос для получения «последних двух выступлений», было бы намного лучше, чем иметь date_of_talk> некоторую дату.
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 или меньше последующих переговоров

Ещё вопросы

Сообщество Overcoder
Наверх
Меню