2016-04-20 4 views
0

У меня есть ситуация, когда мне нужно извлечь записи участников из таблицы «ЧЛЕН». Мне нужно получить фамилию, имя, отношения, имя входа, идентификатор участника, адрес электронной почты и идентификатор сайта. Критерии - это отношение «P», siteid «111» и непустой адрес электронной почты. И мне нужно исключить два подмножества. Подмножество A имеет все вышеперечисленные критерии плюс поле, определяемое пользователем, с идентификатором пользователя, определяющим поле 26, значением поля, определяемым пользователем, «Нет» и датой ввода более 6 дней назад. Подмножество B имеет одни и те же основные критерии, но дату ввода более 2 недель назад и поле, определяемое пользователем, 25 и используемое определенное значение поля 25. Поля и значения, определенные пользователем, хранятся в отдельной таблице (MEMBERUDFS) из Данные участников. Сложная часть - если пользователь не установил значение поля, определенного пользователем, в таблице MEMBERUDFS нет записи. Две таблицы связаны с ключом memid.SQL Exclude через подзапрос

Это то, что у меня есть до сих пор, и это не исключает группу A, и я не пытался добавить логику, чтобы исключить группу B. Любая помощь будет принята с благодарностью !!! :

SELECT MEMBERS.scancode, 
    MEMBERS.memid, 
    MEMBERS.fname, 
    MEMBERS.lname, 
    MEMBERS.relationship, 
    MEMBERS.STATUS, 
    MEMBERS.email, 
    MEMBERS.entrydate, 
    SITES.sitename 
FROM MEMBERS 
INNER JOIN SITES ON MEMBERS.siteid = SITES.siteid 
LEFT OUTER JOIN MEMBERUDFS ON MEMBERS.memid = MEMBERUDFS.memid 
INNER JOIN MEMBERUDFSETUPS ON MEMBERUDFS.udfid = MEMBERUDFSETUPS.udfid 
WHERE (MEMBERS.relationship = 'P') 
    AND (MEMBERS.email <> '') 
    AND (
     MEMBERS.memid NOT IN (
      SELECT MEMBERS_1.memid 
      FROM MEMBERS AS MEMBERS_1 
      INNER JOIN SITES AS SITES_1 ON MEMBERS_1.siteid = SITES_1.siteid 
      LEFT OUTER JOIN MEMBERUDFS AS MEMBERUDFS_1 ON MEMBERS_1.memid = MEMBERUDFS_1.memid 
      INNER JOIN MEMBERUDFSETUPS AS MEMBERUDFSETUPS_1 ON MEMBERUDFS_1.udfid = MEMBERUDFSETUPS_1.udfid 
      WHERE (MEMBERS_1.relationship = 'P') 
       AND (MEMBERS_1.email <> '') 
       AND (MEMBERUDFS_1.udfid = '26') 
       AND (MEMBERUDFS_1.udfvalue = 'No') 
       AND (MEMBERS_1.entrydate < DATEADD(DAY, 6, GETDATE())) 
       AND (MEMBERS_1.siteid = @rvSite) 
      ) 
     ) 
    AND (MEMBERS.siteid = @rvSite) 
+0

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

+0

memid, lname, fname, relationship, email, entrydate, siteid будет 1234, Doe, John, P, [email protected], 04-15-2016 00: 00: 00: 00, 111, где UDF из 26 значение «Нет» – Merlin

+0

В вашем подзапросе вы используете левое соединение с MEMBERUDFS, но тогда у вас также есть предикаты, ссылающиеся на эту таблицу. Этот шаблон фактически превращает это левое соединение во внутреннее соединение. –

ответ

0

Похоже, вы должны быть в состоянии использовать НЕ СУЩЕСТВУЕТ здесь и удалить таблицы UDF из основного запроса, так как вы не выбираете ничего от них.

SELECT MEMBERS.scancode, 
    MEMBERS.memid, 
    MEMBERS.fname, 
    MEMBERS.lname, 
    MEMBERS.relationship, 
    MEMBERS.STATUS, 
    MEMBERS.email, 
    MEMBERS.entrydate, 
    SITES.sitename 
FROM MEMBERS 
INNER JOIN SITES ON MEMBERS.siteid = SITES.siteid 
WHERE (MEMBERS.relationship = 'P') 
    AND (MEMBERS.email <> '') 
    AND (MEMBERS.siteid = @rvSite) 
    AND NOT EXISTS (
     SELECT 1 
     FROM MEMBERUDFS AS MEMBERUDFS_1 ON MEMBERS_1.memid = MEMBERUDFS_1.memid 
       INNER JOIN MEMBERUDFSETUPS AS MEMBERUDFSETUPS_1 ON MEMBERUDFS_1.udfid = MEMBERUDFSETUPS_1.udfid 
     WHERE MEMBERS.memid = MEMBERUDFS_1.memid 
       AND (MEMBERUDFS_1.udfid = '26') 
       AND (MEMBERUDFS_1.udfvalue = 'No') 
       AND (MEMBERS.entrydate < DATEADD(DAY, 6, GETDATE())) 
    ) 
+0

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

+0

@TabAlleman да не уверен в уникальности memid, но он будет иметь другой результат, потому что вы вынимаете JOIN в MEMBERUDFSETUPS, так как эти записи могут не существовать. – JamieD77

+0

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

0

Не могли бы вы перефразировать запрос таким образом:

SELECT MEMBERS.scancode, 
    MEMBERS.memid, 
    MEMBERS.fname, 
    MEMBERS.lname, 
    MEMBERS.relationship, 
    MEMBERS.STATUS, 
    MEMBERS.email, 
    MEMBERS.entrydate, 
    SITES.sitename 
FROM MEMBERS 
INNER JOIN SITES ON MEMBERS.siteid = SITES.siteid 
LEFT OUTER JOIN MEMBERUDFS ON MEMBERS.memid = MEMBERUDFS.memid 
INNER JOIN MEMBERUDFSETUPS ON MEMBERUDFS.udfid = MEMBERUDFSETUPS.udfid 
WHERE (MEMBERS.relationship = 'P') 
    AND (MEMBERS.email <> '') 
    AND (MEMBERS.siteid = @rvSite) 
    AND NOT (MEMBERS.entrydate < DATEADD(DAY, 6, GETDATE()) AND EXISTS 
     (SELECT memid FROM MEMBERUDFS WHERE (MEMBERUDFS.udfid = '26') 
     AND (MEMBERUDFS.udfvalue = 'No') 
     AND (MEMBERUDFS.memid = MEMBERS.memid))) 
+0

Нет, это не та же логика. Это вернет MemIds, где есть значение UDF 26/No, если есть другие строки, относящиеся к тому же MemId, которые не являются. –

+0

Джентльмены, я выяснил этот вопрос со всей вашей помощью. Проблема, похоже, заключалась в том, что, как только я переместил некоторую логику исключения в подзапрос, я больше не требовал всех JOINS в основном запросе. Как только я удалил эти строки, я смог вытащить правильные данные с исключением подзапроса A. Теперь мне просто нужно добавить логику для подзапроса B, и я буду установлен. Это запрос, который работал для подзапроса A: – Merlin

+0

SELECT DISTINCT scancode, memid, fname, lname, relationship, status, email, entrydate ОТ ЧЛЕНОВ WHERE (отношение = 'P') AND (email <> '') AND (siteid = @rvSite) И – Merlin