代码之家  ›  专栏  ›  技术社区  ›  Carson Myers

这个连接查询有什么问题?

  •  1
  • Carson Myers  · 技术社区  · 15 年前

    我有一个租户报告列表,每个链接指向一个报告ID。

    我需要这个查询来选择报告信息,以及一些与提交它的租户相关的信息。

    此查询正确获取报表信息,但返回报表的副本,每个租户都附加到该查询上:

    SELECT 
    reports.person_reporting, reports.request_type, reports.details, tenants.office,
    tenants.email, tenants.alt_email, tenants.office_phone, tenants.personal_cell,
    tenants.emergency_phone, tenants.address, tenants.building_name
    FROM reports, tenants
    WHERE reports.id = '{$id}'
    AND (
        tenants.email = reports.email
        OR tenants.alt_email = reports.alt_email
    )
    

    在那 AND 子句,我需要它将租户的电子邮件地址与报表中包含的具有指定ID的电子邮件地址相匹配。但它只是为每个租户提供与报表中的任何电子邮件或备用电子邮件相匹配的电子邮件或备用电子邮件(几乎所有电子邮件,因为大多数都没有指定备用电子邮件)。

    我有什么办法吗?

    更新

    我的问题是有很多空的alt_电子邮件字段,它只是选择了所有字段。下面的答案在过滤空字段时是正确的,但我只是将OR子句改为AND子句,这更清楚地说明了我希望如何匹配它们:它们都必须匹配,因为数据库中不应该有任何重复的电子邮件。

    2 回复  |  直到 15 年前
        1
  •  3
  •   FryGuy    15 年前

    你应该像这样过滤掉“空”邮件。

    AND (
        (tenants.email != '' AND tenants.email = reports.email) OR
        (tenants.alt_email != '' AND tenants.alt_email = reports.alt_email)
    )
    

    实际上,这似乎应该是一个左连接,即:

    SELECT 
    reports.person_reporting, reports.request_type, reports.details, tenants.office,
    tenants.email, tenants.alt_email, tenants.office_phone, tenants.personal_cell,
    tenants.emergency_phone, tenants.address, tenants.building_name
    FROM reports
    LEFT JOIN tenants ON (
        (tenants.email != '' AND tenants.email = reports.email)
        OR (tenants.alt_email != '' AND tenants.alt_email = reports.alt_email)
    )
    WHERE reports.id = '{$id}'
    

    这样,您将至少获得一次没有租户的报告。

        2
  •  3
  •   delfuego    15 年前

    我假设你的问题是有一堆租户alt_email=null,还有一堆报告alt_email=null,你的or子句会将每个报告与alt_email=null匹配 全部的 租户记录alt_email=空。

    您可能应该捕获空的大小写:

    WHERE reports.id = '{$id}'
    AND (
      (tenants.email IS NOT NULL AND tenants.email = reports.email)
      OR (tenants.alt_email IS NOT NULL AND tenants.alt_email = reports.alt_email)
    )