这个JOIN查询有什么问题?

时间:2009-12-16 02:23:01

标签: sql mysql join

我有一份租户报告列表,每个链接都指向一个报告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_email字段,它只是挑选了所有这些字段。过滤掉空字段时,下面的答案是正确的,但我只是将我的OR子句更改为AND子句,这更清楚我想如何匹配它们:它们都必须匹配,因为不应该有任何重复数据库中的电子邮件。

2 个答案:

答案 0 :(得分:3)

你应该过滤掉'null'电子邮件,就像这样。

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}'

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

答案 1 :(得分:3)

我认为您的问题是有一堆租户使用alt_email = NULL,以及一堆使用alt_email = NULL的报告,并且您的OR子句将匹配每个报告,alt_email = NULL且全部使用alt_email = NULL的租户记录。

你应该抓住NULL情况:

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)
)