查找哪个ID数组没有单个查询的记录

时间:2016-02-11 02:44:01

标签: mysql join pdo

我使用PHP PDO生成预准备语句,以根据ID数组从两个表中提取信息。

然后我意识到,如果通过的身份证没有记录,我就不会知道。

我用

查找记录
SELECT 
    r.`DEANumber`, 
    TRIM(r.`ActivityCode`) AS ActivityCode, 
    TRIM(r.`ActivitySubCode`) as ActivitySubCode, 
    // other fields...
    a.Activity
FROM 
    `registrants` r,
    `activities` a
WHERE r.`DEAnumber` IN ( ?,?,?,?,?,?,?,? )
    AND a.Code = ActivityCode
    AND a.Subcode = ActivitySubCode

但我无法弄清楚哪个ID没有记录的负面联接。

如果涉及两张表,我想我可以这样做

SELECT
r.DEAnumber
FROM registrant r
LEFT JOIN registrant2 r2 ON r.DEAnumber = r2.DEAnumber
WHERE r2.DEAnumber IS NULL

但是我在这里难以理解如何使用ID数组。显然,我可以迭代数组并跟踪哪些查询没有结果,但这似乎是一种手动和浪费的方式......

2 个答案:

答案 0 :(得分:2)

  

显然,我可以迭代数组并跟踪哪些查询没有结果,但这似乎是一种手动和浪费的方式。

可能是真正的浪费是花时间解决这个不存在的问题"。

是的,你可以迭代。手动,或在PHP中使用类似array_diff()的语法糖。

我建议你不要让你的查询更复杂(意味着更重要的支持)以获得微不足道的收益,而是继续前进。

正如老人克努特曾经说过的那样,过早的优化是所有邪恶的根源。

我唯一能想到PDO帮助的是fetch mode that will put IDs as keys for the returned array,因此您可以在没有[明确书写]循环的情况下制作它,例如

$stmt->execute($ids);
$data = $stmt->fetchAll(PDO::FETCH_UNIQUE);
$notFound = array_diff($ids, array_keys($data));

然而,手动循环只需要两条额外的线路,老实说,这并不是一件大事。

答案 1 :(得分:0)

您走在正确的轨道上 - 过滤 out 匹配的左连接将为您提供缺少的连接。您只需将左连接表上的所有条件移动到连接中。

如果将条件保留在where子句中的联接表上,则会有效地导致内部联接,因为在联接之后对行执行where子句如果首先没有加入,那就太迟了。

更改查询以使用正确的连接语法,指定连接,并将activity上的条件移至连接&n; {n} on子句:

SELECT 
    r.DEANumber, 
    TRIM(r.ActivityCode) AS ActivityCode, 
    TRIM(r.ActivitySubCode) as ActivitySubCode, 
    // other fields...
    a.Activity
FROM registrants r
LEFT JOIN activities a ON a.Code = ActivityCode
    AND a.Subcode = ActivitySubCode
WHERE r.DEAnumber IN (?,?,?,?,?,?,?,?)

在您的应用代码中,如果Activitynull,那么您知道该ID没有任何活动。

这不会影响性能,除了返回(可能)更多行。

只选择没有活动的所有注册人:

select r.DEAnumber
from registrants r
left join activities a on a.Code = ActivityCode
    and a.Subcode = ActivitySubCode
where r.`DEAnumber` IN ( ?,?,?,?,?,?,?,? )
and a.Code is null