我目前有以下查询,该查询使用UNION联接连接两个查询和SQL变量,以交替显示行数在总和与活动数之间的顺序。当我将SET行添加到查询中时,PHP文件有一个错误,当我删除它们时,查询会运行,但不会检索到任何值。我已经在服务器上运行查询,并且可以正常工作。
如何在准备好的语句中使用SQL变量?如果不可能,我将如何重写查询以获得相同的结果?
SET @a = 0;
SET @b = 0;
SELECT * FROM(
SELECT @a := @a + 1 AS sortOne, 1 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
SUM(tbl_short_term_programme.sun_p) AS sun_p_total, SUM(tbl_short_term_programme.sun_a) AS sun_a_total,
SUM(tbl_short_term_programme.mon_p) AS mon_p_total, SUM(tbl_short_term_programme.mon_a) AS mon_a_total,
SUM(tbl_short_term_programme.tue_p) AS tue_p_total, SUM(tbl_short_term_programme.tue_a) AS tue_a_total,
SUM(tbl_short_term_programme.wed_p) AS wed_p_total, SUM(tbl_short_term_programme.wed_a) AS wed_a_total,
SUM(tbl_short_term_programme.thu_p) AS thu_p_total, SUM(tbl_short_term_programme.thu_a) AS thu_a_total,
SUM(tbl_short_term_programme.fri_p) AS fri_p_total, SUM(tbl_short_term_programme.fri_a) AS fri_a_total,
SUM(tbl_short_term_programme.sat_p) AS sat_p_total, SUM(tbl_short_term_programme.sat_a) AS sat_a_total
FROM tbl_short_term_programme
INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
GROUP BY tbl_shift.shift_id, tbl_company.comp_name
UNION
SELECT @b := @b + 1 AS sortOne, 2 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
COUNT(tbl_short_term_programme.sun_p) AS sun_p_total, COUNT(tbl_short_term_programme.sun_a) AS sun_a_total,
COUNT(tbl_short_term_programme.mon_p) AS mon_p_total, COUNT(tbl_short_term_programme.mon_a) AS mon_a_total,
COUNT(tbl_short_term_programme.tue_p) AS tue_p_total, COUNT(tbl_short_term_programme.tue_a) AS tue_a_total,
COUNT(tbl_short_term_programme.wed_p) AS wed_p_total, COUNT(tbl_short_term_programme.wed_a) AS wed_a_total,
COUNT(tbl_short_term_programme.thu_p) AS thu_p_total, COUNT(tbl_short_term_programme.thu_a) AS thu_a_total,
COUNT(tbl_short_term_programme.fri_p) AS fri_p_total, COUNT(tbl_short_term_programme.fri_a) AS fri_a_total,
COUNT(tbl_short_term_programme.sat_p) AS sat_p_total, COUNT(tbl_short_term_programme.sat_a) AS sat_a_total
FROM tbl_short_term_programme
INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
GROUP BY tbl_shift.shift_id, tbl_company.comp_name
) AS result ORDER BY sortOne, sortTwo
$stmt->bind_param("ssss", $phase_hash, $formatted_date, $phase_hash, $formatted_date);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($comp_name, $shift_name, $sun_p_total, $sun_a_total, $mon_p_total, $mon_a_total, $tue_p_total,
$tue_a_total, $wed_p_total, $wed_a_total, $thu_p_total, $thu_a_total, $fri_p_total, $fri_a_total,
$sat_p_total, $sat_a_total);
$row_array = array();
while($stmt->fetch()) {
$tmp = array();
$tmp["shift_name"] = $shift_name;
$tmp["comp_name"] = $comp_name;
$tmp["sun_p_total"] = $sun_p_total;
$tmp["sun_a_total"] = $sun_a_total;
$tmp["mon_p_total"] = $mon_p_total;
$tmp["mon_a_total"] = $mon_a_total;
$tmp["tue_p_total"] = $tue_p_total;
$tmp["tue_a_total"] = $tue_a_total;
$tmp["wed_p_total"] = $wed_p_total;
$tmp["wed_a_total"] = $wed_a_total;
$tmp["thu_p_total"] = $thu_p_total;
$tmp["thu_a_total"] = $thu_a_total;
$tmp["fri_p_total"] = $fri_p_total;
$tmp["fri_a_total"] = $fri_a_total;
$tmp["sat_p_total"] = $sat_p_total;
$tmp["sat_a_total"] = $sat_a_total;
array_push($row_array, $tmp);
}
$stmt->close();
echo json_encode($row_array);
答案 0 :(得分:1)
正如Bill Karwin所说,您只能在准备好的语句中运行一个查询。解决该问题的另一种方法是在与主查询连接的子查询中分配变量。
SELECT * FROM(
SELECT @a := @a + 1 AS sortOne, 1 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
SUM(tbl_short_term_programme.sun_p) AS sun_p_total, SUM(tbl_short_term_programme.sun_a) AS sun_a_total,
SUM(tbl_short_term_programme.mon_p) AS mon_p_total, SUM(tbl_short_term_programme.mon_a) AS mon_a_total,
SUM(tbl_short_term_programme.tue_p) AS tue_p_total, SUM(tbl_short_term_programme.tue_a) AS tue_a_total,
SUM(tbl_short_term_programme.wed_p) AS wed_p_total, SUM(tbl_short_term_programme.wed_a) AS wed_a_total,
SUM(tbl_short_term_programme.thu_p) AS thu_p_total, SUM(tbl_short_term_programme.thu_a) AS thu_a_total,
SUM(tbl_short_term_programme.fri_p) AS fri_p_total, SUM(tbl_short_term_programme.fri_a) AS fri_a_total,
SUM(tbl_short_term_programme.sat_p) AS sat_p_total, SUM(tbl_short_term_programme.sat_a) AS sat_a_total
FROM tbl_short_term_programme
INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
CROSS JOIN (SELECT @a := 0) AS var
WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
GROUP BY tbl_shift.shift_id, tbl_company.comp_name
UNION
SELECT @b := @b + 1 AS sortOne, 2 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
COUNT(tbl_short_term_programme.sun_p) AS sun_p_total, COUNT(tbl_short_term_programme.sun_a) AS sun_a_total,
COUNT(tbl_short_term_programme.mon_p) AS mon_p_total, COUNT(tbl_short_term_programme.mon_a) AS mon_a_total,
COUNT(tbl_short_term_programme.tue_p) AS tue_p_total, COUNT(tbl_short_term_programme.tue_a) AS tue_a_total,
COUNT(tbl_short_term_programme.wed_p) AS wed_p_total, COUNT(tbl_short_term_programme.wed_a) AS wed_a_total,
COUNT(tbl_short_term_programme.thu_p) AS thu_p_total, COUNT(tbl_short_term_programme.thu_a) AS thu_a_total,
COUNT(tbl_short_term_programme.fri_p) AS fri_p_total, COUNT(tbl_short_term_programme.fri_a) AS fri_a_total,
COUNT(tbl_short_term_programme.sat_p) AS sat_p_total, COUNT(tbl_short_term_programme.sat_a) AS sat_a_total
FROM tbl_short_term_programme
INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
CROSS JOIN (SELECT @b :- 0) AS var
WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
GROUP BY tbl_shift.shift_id, tbl_company.comp_name
) AS result ORDER BY sortOne, sortTwo
答案 1 :(得分:0)
默认情况下,每次调用mysqli_prepare()
只能运行一个SQL语句。
我建议在单独的语句中设置会话变量:
$mysqli->query("set @a = 0, @b = 0");
然后为大型查询做准备和执行。
有些人可能会告诉您使用mysqli_multi_query()函数,但您不能这样做,因为它不支持准备好的语句。
没关系,在单个调用中执行多个查询没有优势。只需在一个调用中设置变量,然后执行准备好的语句即可。只要您使用相同的数据库连接,会话变量仍将具有其值。