我可以仅使用一个查询来查找数组中的哪些值没有相应的数据库记录吗?

Can I find which values in an array do not have corresponding database records using only one query?

我有一个数组,其中包含一些从上传文件中获取的值。我想确定文件中的哪些值在我的数据库中是 而不是

我已经知道如何通过遍历数组并检查数据库中每个值的匹配记录来一次检查一个值。

$stmt = $pdo->prepare('SELECT COUNT(*) FROM my_table WHERE a_column = ?');
foreach ($values as $value) {
    $stmt->execute([$value]);
    if ($stmt->fetchColumn() === '0')   // do something with $value
}

但我想知道是否有一种方法可以在一个查询中获得结果。如果我已经有了 SQL table 中的值,通过加入 table 并检查结果,很容易找到另一个 table 中具有匹配值的值对于有问题的 table 中的空值。

SELECT i.value
FROM
    imaginary_values_table i
    LEFT JOIN my_table m ON i.value = m.a_column
WHERE
    m.id IS NULL

是否可以使用值列表来执行此类查询?

我熟悉 IN,但我不知道如何直接将其用于此目的,因为我正在尝试查找数组 中的哪些项 不在 table 中。使用 IN 我可以获得数组中 table 中的所有行,或者使用 NOT IN 我可以获得不在我的数组中的所有行。

您可以使用这样的查询:

SELECT t1.val
FROM (SELECT 1 AS val
      UNION
      SELECT 2 AS val
      UNION
      SELECT 3 AS val
      ...) AS t1
LEFT JOIN my_table AS t2 ON t1.val = t2.a_column
WHERE t2.a_column IS NULL

您可以从值数组构建 UNION 子查询:

$union = implode(' UNION ', array_map(function($val) {
    return "SELECT $val AS val";
}, $array));

我找到了一种不同的方法来执行此操作,方法是使用 IN 选择与数组中的值匹配的所有行,然后使用 array_diff 与原始数组和查询结果来获取这些行那不存在。

$qs = rtrim(str_repeat('?,', count($values)),',');
$stmt = $pdo->prepare("SELECT a_column FROM my_table WHERE a_column IN ($qs)");
$stmt->execute($values);
$not_there = array_diff($values, $stmt->fetchAll(PDO::FETCH_COLUMN));