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.id
、b.pat_id
和 c.pat_id
.[=17= 上至少有一个条目的行]
可能您对 LEFT JOIN 更感兴趣,它将 return pat_info
的所有条目扩展为 pat_medication
和 prn_medication
无论您有数据还是不要在这两个 tables.
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
吗?
它们也应该绑定到一些数据。
我正在尝试使用 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.id
、b.pat_id
和 c.pat_id
.[=17= 上至少有一个条目的行]
可能您对 LEFT JOIN 更感兴趣,它将 return pat_info
的所有条目扩展为 pat_medication
和 prn_medication
无论您有数据还是不要在这两个 tables.
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
吗?
它们也应该绑定到一些数据。