2015-07-07 5 views
0

Я пытаюсь создать запрос, который ТОЛЬКО выводит члены, если они отвечают двум условиям.MYSQL: несколько «противоречащих» условий в одном столбце

Первое условие: Если у пользователя есть соответствующий «идентификатор курса».

Второе условие: Если у пользователя нет соответствующего «курсаID».

Очевидно, это противоречит, поэтому позвольте мне объяснить.

У меня есть две таблицы ...

членов

  • ID
  • электронной

сертификаты

  • ID
  • MemberID
  • courseID

Когда члены закончить курс они получают сертификат. Сертификация хранит их идентификатор memberID и идентификатор курса. Члены могут иметь несколько сертификатов.

Конечной целью является создание списка отправки электронной почты для продвижения курсов.

Предположим, у нас есть два курса. «Начальный» (курс = 1) и «Промежуточный» (курс ID = 2).

Один член может иметь как сертификаты, по одному для каждого курса. У другого члена может быть только одна, сертификация «Новичок».

Я хочу отправить рекламное письмо всем членам, имеющим сертификат «Новичок». Однако я хочу исключить всех членов с сертификатом «Промежуточный».

Проблема, которую я не могу преодолеть, заключается в том, как исключить членов с сертификатом «Промежуточный».

** я упростил этот пример, на самом деле существует огромное количество различных типов сертификации **

Ниже грубый вопрос я пытался ... Я пытался так, что многие разные запросы.

Любая помощь будет замечательной, спасибо.

// Look Up Recipients 
$recipientsQuery = $wpdb->get_results(" 
SELECT DISTINCT(email) 
FROM $memberTable 
LEFT JOIN $certificationsTable 
ON $memberTable.ID = $certificationsTable.memberID 
WHERE courseID = 4 AND courseID != 5 
"); 
+0

Не было бы проще, если бы новичок был сохранен как 1 и промежуточный как 2? – Strawberry

ответ

0
SELECT m.ID, m.email 
    , MAX(IF(c.courseID = 4, 1, 0)) AS hasCourse4 
    , MAX(IF(c.courseID = 5, 1, 0)) AS hasCourse5 
FROM members AS m 
LEFT JOIN certifications AS c ON m.ID = c.memberID 
HAVING hasCourse4 = 1 AND hasCourse5 = 0 
; 

В качестве альтернативы, вы можете присоединиться к членам сертификаты на сертификаты, это может быть быстрее:

SELECT m.email 
FROM certifications AS c1 
INNER JOIN members AS m ON c1.memberID = m.ID 
LEFT JOIN certifications AS c2 ON m.ID = c2.memberID AND c2.courseID = 5 
WHERE c1.courseID = 4 AND c2.courseID IS NULL 
; 
+0

Я получил второй запрос, спасибо за вашу помощь! :-) –

+0

@DeanRidgeley Из любопытства у вас возникли проблемы с первым? – Uueerdo

+0

Я пробовал первый и не повезло, но оглядываясь назад, я думаю, что это была моя ошибка, так как я забыл сделать настройку. –

0

Попробуйте это .. Получите то, что вам нужно, и забрать то, что вы не ..

SELECT * 
FROM $memberTable 
LEFT JOIN $certificationsTable USING (ID) 
WHERE courseID = 4 
AND ID NOT IN (
    SELECT ID 
    FROM $memberTable 
    LEFT JOIN $certificationsTable USING (ID) 
    WHERE courseID = 5 
) 
+0

'И ИД' является двусмысленным. И на самом деле внешний запрос не должен быть LEFT-соединением, а подзапрос в том, где, вероятно, на самом деле не требуется соединение с членами. – Uueerdo

+0

Привет Крис, спасибо за вашу помощь. Я думаю, что это почти есть, но я не могу заставить его работать. Мне сложно понять, как соединяются таблицы? Когда я попробовал свой код, он отобразил одного человека, который является правильным номером на данный момент, однако он был не тот человек, даже не получил сертификацию. Не могли бы вы снова помочь мне? –

+0

Кроме того, условие соединения внешнего запроса неверно; это сопоставление 'members.ID' с' certifications.ID', а не 'certifications.memberID' – Uueerdo

Смежные вопросы