SQL查询(显示所有“ x”,其中“ x”不在字段“ y”的表“ 2”中并且具有“ z”标志)

时间:2019-04-02 12:07:26

标签: sql ms-access

我需要返回所有未出现在“代表”表中的“事件名称”,但在“联系人”表中具有可由用户选择以进行搜索的标志的所有“联系人”。

我知道查询可以分为2部分。

  1. 他们是否已经参加了此活动(他们的电子邮件是否出现在“ delegates”表中,并且带有与用户窗体上的“ event”相匹配的delegates.event字段)
WHERE (
  d.Event <> [Forms]![usf_FindCampaignContacts]![FCC_EventName]
  1. 它们是否符合条件(他们是否在“联系人”表中获得了HR标志)
  AND (c.[HR-DEL]   = [Forms]![usf_FindCampaignContacts]![FCC_HRD]   OR IsNull([Forms]![usf_FindCampaignContacts]![FCC_HRD]));

基于执行查询所需的两件事,我编写了以下代码...

SELECT 
c.[First Name], c.[Last Name], c.Email, d.Event, c.Suppress, c.[HR-DEL]

FROM tbl_Contacts AS c LEFT JOIN tbl_Delegates AS d ON c.Email = d.Email

WHERE (
  d.Event <> [Forms]![usf_FindCampaignContacts]![FCC_EventName]
  And 
  c.Suppress = False
) 
  AND (c.[HR-DEL]   = [Forms]![usf_FindCampaignContacts]![FCC_HRD]   OR IsNull([Forms]![usf_FindCampaignContacts]![FCC_HRD]));

[FCC_HRD]指的是用户在表单上选择的输入,我尝试使用<>删除匹配的记录,但是我感觉这是编译错误所在,因此我将这些更改为and / or语句,现在将这一部分返回带有匹配标志(成功)的结果

尝试以这种方式进行操作的其他问题是,即使它起作用,也会删除“委托人/赞助者”表中列出的任何人。这就是为什么我为事件添加<>语句的原因,因为它只需要将它们从命名事件的列表中删除即可。再次,这很完美(成功)

最后一个问题是,结果显然是从“代理”表而不是“联系人”表中拉出的,因为以上两个部分都在工作,而仅在代表表中显示了与条件匹配的结果,而不是从联系人中。

Here is the query/table relationships

Here is the user form(这不是最终设计)

下面是查询中使用的3个表(2个直接表,1个链接表) 联系人(c)

+----+------------+---------------+-------------------------+--------+----------+
| ID | First Name |   Last Name   |          Email          | HR-DEL | Suppress |
+----+------------+---------------+-------------------------+--------+----------+
|  1 | A          | Platt         | a.platt@fake.com        | TRUE   | TRUE     |
|  2 | D          | Farr          | d.farr@fake.com         | TRUE   | FALSE    |
|  3 | Y          | Helle         | y.helle@fake.com        | TRUE   | FALSE    |
|  4 | S          | Oliphant      | soliphant@fake.com      | TRUE   | FALSE    |
|  5 | J          | Bedell-Pearce | jbedell-pearce@fake.com | TRUE   | FALSE    |
|  6 | J          | Walker        | j.walker@fake.com       | FALSE  | FALSE    |
|  7 | S          | Rug           | s.rug@fake.com          | FALSE  | FALSE    |
|  8 | D          | Brown         | d.brown@fake.com        | FALSE  | FALSE    |
|  9 | R          | Cooper        | r.cooper@fake.com       | TRUE   | FALSE    |
| 10 | M          | Morrall       | m.morrall@fake.com      | TRUE   | FALSE    |
+----+------------+---------------+-------------------------+--------+----------+

代表(d)

+----+-------------------------+-------+
| ID |          Email          | Event |
+----+-------------------------+-------+
|  1 | a.platt@fake.com        |     2 |
|  2 | d.farr@fake.com         |     1 |
|  3 | y.helle@fake.com        |     4 |
|  4 | soliphant@fake.com      |     3 |
|  6 | jbedell-pearce@fake.com |     2 |
+----+-------------------------+-------+

事件(不是直接事件,而是用于检查用户表单上的事件名称下拉列表与委托中的事件编号)

+----+------------+
| ID | Event Name |
+----+------------+
|  1 | Test 1     |
|  2 | Test 2     |
|  3 | Test 3     |
|  4 | Test 4     |
+----+------------+

基于表单选择和此示例数据,我需要返回以下内容:

所有标记为“ HR”为TRUE,未被抑制或进入名为“ test 2”的事件的联系人(应该为5-我总是返回“代表”的姓名,而不是仅参加事件= 3)

最终结果应该是:

+----+------------+-----------+--------------------+--------+----------+
| ID | First Name | Last Name |       Email        | HR-DEL | Suppress |
+----+------------+-----------+--------------------+--------+----------+
|  2 | D          | Farr      | d.farr@fake.com    | TRUE   | FALSE    |
|  3 | Y          | Helle     | y.helle@fake.com   | TRUE   | FALSE    |
|  4 | S          | Oliphant  | soliphant@fake.com | TRUE   | FALSE    |
|  9 | R          | Cooper    | r.cooper@fake.com  | TRUE   | FALSE    |
| 10 | M          | Morrall   | m.morrall@fake.com | TRUE   | FALSE    |
+----+------------+-----------+--------------------+--------+----------+

目前,它似乎是从错误的表(d不是c)中提取结果。我试图更改为OUTER联接类型,但返回了FROM语法错误。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,基本上您想这样做:

SELECT A.foo
FROM A 
  LEFT JOIN B 
    ON A.bar = B.bar
WHERE
  <complex condition, partly involving B>

这不起作用。通过在全局WHERE条件中包括B,可以将LEFT JOIN转换为INNER JOIN,因此,您将永远只获得与A和B之间匹配的记录。

您可以将B上的过滤器移到JOIN条件:

SELECT A.foo
FROM A 
  LEFT JOIN B 
    ON (A.bar = B.bar)
    AND (B.bamboozle = 42)
WHERE
  A.columns = things

或LEFT JOIN一个过滤的子查询:

SELECT A.foo
FROM A 
  LEFT JOIN 
    (SELECT bar, columns FROM B 
     WHERE B.bamboozle = 42) AS B1
    ON A.bar = B1.bar
WHERE
  A.columns = things

因此,在您的查询中,这是您需要移动的 bamboozle 部分:

d.Event <> [Forms]![usf_FindCampaignContacts]![FCC_EventName]