UNION ALL 的数组绑定问题

Array binding issue with UNION ALL

我正在尝试使用 UNION ALL 连接多个查询。

我尝试了以下代码。这给出了 Invalid parameter number: number of bound variables does not match number of tokens.

的错误
$code = '1,2,3,4';
$codeArray = explode(',', $code);
$inQuery = implode(',', array_fill(0, count($codeArray), '?'));    
$full_dt = date('Y-m-d H:i:s');
$start_date = "2020-08-28 14-44-23";
$medication = "OD";
    $query = "SELECT SUM(counts) AS allcounts FROM
  (SELECT COUNT(b.id) AS counts
   FROM pat_info a
   INNER JOIN pat_medication b ON a.id = b.pat_id
   WHERE a.status != 2
     AND b.status != 2
     AND b.directions = '$medication'
     AND b.last_med_time < '$start_date'
     AND '$full_dt' BETWEEN b.start_date AND b.end_date
     AND a.location_code IN($inQuery)
   UNION ALL SELECT COUNT(d.id) AS counts
   FROM pat_info c
   INNER JOIN prn_medication d ON c.id = d.pat_id
   WHERE c.status != 2
     AND d.status != 2
     AND d.dose_frequency = '$medication'
     AND d.last_med_time < '$start_date'
     AND '$full_dt' BETWEEN d.start_date AND d.end_date
     AND c.location_code IN($inQuery) ) x ";
    $statement = $conn->prepare($query);
    $codeArray = array_merge($codeArray, $codeArray);
    $statement->execute($codeArray);

print_r($inQuery);结果?,??,?

print_r($codeArray);

array_merge($codeArray, $codeArray);

之前

结果Array ( [0] => 1 [1] => 2 ) Array ( [0] => 1 [1] => 2 [2] => 1 [3] => 2 )

print_r($codeArray);

array_merge($codeArray, $codeArray);

之后

结果Array ( [0] => 1 [1] => 2 [2] => 1 [3] => 2 ) Array ( [0] => 1 [1] => 2 [2] => 1 [3] => 2 [4] => 1 [5] => 2 [6] => 1 [7] => 2 )

INNER JOIN return 在每个 table 中都有数据时的结果。这意味着 return 行将是在每个 table 共享 a.idb.pat_idc.pat_id.[=17= 上至少有一个条目的行]

可能您对 LEFT JOIN 更感兴趣,它将 return pat_info 的所有条目扩展为 pat_medicationprn_medication 无论您有数据还是不要在这两个 tables.

https://dev.mysql.com/doc/refman/5.7/en/join.html

select * 从 表A 内部联接 表b 在 a.common = b.common 内部联接 表抄送 在 b.common = c.common

问题应该是'?'的数量与您传递的参数数量不匹配。

在“$statement->execute($codeArray)”中,$codearray 的元素数量应与逗号分隔的“?”数量相同在 $查询中。 您与“With print_r($inQuery); 结果 ?,??,?” 分享的内容看起来很有趣,它不应该是逗号分隔的问号序列吗?

我认为在这种情况下使用带命名参数的bindParam是一个很好的策略,例如:

$code = '1,2,3,4';
$full_dt = date('Y-m-d H:i:s');
$start_date = "2020-08-28 14-44-23";
$medication = "OD";
    $query = "SELECT SUM(counts) AS allcounts FROM
  (SELECT COUNT(b.id) AS counts
   FROM pat_info a
   INNER JOIN pat_medication b ON a.id = b.pat_id
   WHERE a.status != 2
     AND b.status != 2
     AND b.directions = :medication
     AND b.last_med_time < :start_date
     AND :full_dt BETWEEN b.start_date AND b.end_date
     AND FIND_IN_SET(a.location_code, :code)>0
   UNION ALL SELECT COUNT(d.id) AS counts
   FROM pat_info c
   INNER JOIN prn_medication d ON c.id = d.pat_id
   WHERE c.status != 2
     AND d.status != 2
     AND d.dose_frequency = :medication
     AND d.last_med_time < :start_date
     AND :full_dt BETWEEN d.start_date AND d.end_date
     AND FIND_IN_SET(c.location_code, :code)>0 ) x ;";
    $statement = $conn->prepare($query);
    $statement->bindParam(':code', $code, PDO::PARAM_STR);
    $statement->bindParam(':full_dt', $full_dt, PDO::PARAM_STR);
    $statement->bindParam(':start_date', $start_date, PDO::PARAM_STR);
    $statement->bindParam(':medication', $medication, PDO::PARAM_STR);
    $statement->execute();

绑定所有参数

看看$full_dt = date('Y-m-d H:i:s');

让我们回应查询并仔细查看这一部分:

...
...
AND '2020-09-16 18:57:31' BETWEEN d.start_date AND d.end_date
...
...

然后我们去看文档:https://www.php.net/manual/en/pdostatement.bindparam.php#refsect1-pdostatement.bindparam-parameters

Parameter identifier. For a prepared statement using named placeholders, this will be a parameter name of the form :name. For a prepared statement using question mark placeholders, this will be the 1-indexed position of the parameter.

你能看到来自:i和来自date('Y-m-d H:i:s'):s两位不速之客:57:31吗?

它们也应该绑定到一些数据。