如何在此请求中添加“ordered by created_on asc”:
(select user.first_name as prenom, user.last_name as nom, fvll.created_on, fvll.bar_code, "R" from stk_fuel_voucher_line fvll,stk_fuel_voucher fv, adm_user user
where YEAR(fvll.created_on)=? and MONTH(fvll.created_on) = ? and user.id=fv.id_user and fv.id=fvll.id_fuel_voucher and
fvll.bar_code not in
(select fvl.bar_code
from stk_fuel_voucher_line fvl, stk_fuel_voucher_book fvb
where fvl.bar_code >= fvb.first_bar_code and fvl.bar_code <=fvb.last_bar_code
and YEAR(fvl.created_on)=? and MONTH(fvl.created_on) = ?))
UNION
(select user2.first_name as prenom, user2.last_name as nom, fvll2.created_on, fvll2.bar_code, "B"
from stk_fuel_voucher fv2, stk_fuel_voucher_book fvb2, stk_fuel_voucher_line fvll2, adm_user user2
where fvll2.bar_code >= fvb2.first_bar_code and fvll2.bar_code <=fvb2.last_bar_code and user2.id=fv2.id_user and fv2.id=fvll2.id_fuel_voucher
and YEAR(fvll2.created_on)=? and MONTH(fvll2.created_on) = ?)
答案 0 :(得分:0)
在我看来,两个查询是相同的,唯一的区别是检测是否有匹配的bar_code,并返回&#39; B&#39;或者&#39; R&#39;根据
我避免了UNION的冗余严重性,只做一个查询,并通过条件测试来确定是否有&#39; B&#39;或者&#39; R&#39;归还。
如果UNION
运算符(代替更常见的UNION ALL
)的意图是从每个集合中删除重复项,我们可以使用GROUP BY
子句或{{1} }关键字来实现这一点。 (在原始查询中,我们保证两组之间不会重复,总是设置为&#39; R&#39;,另一组总是有&#39; B&#39; ;
我不了解查询的规范,但基于我能够从现有查询中辨别的内容,我倾向于做这样的事情:
DISTINCT
同样,如果我们不关心删除重复项,那么我们可以删除SELECT user.first_name AS prenom
, user.last_name AS nom
, fvll.created_on AS created_on
, fvll.bar_code
, CASE WHEN ni.bar_code IS NULL THEN 'R' ELSE 'B' END AS r
FROM stk_fuel_voucher_line fvll
JOIN stk_fuel_voucher fv
ON fv.id = fvll.id_fuel_voucher
JOIN adm_user user
ON user.id = fv.id_user
LEFT
JOIN ( SELECT fvl.bar_code
FROM stk_fuel_voucher_line fvl
JOIN stk_fuel_voucher_book fvb
ON fvb.first_bar_code <= fvl.bar_code
AND fvb.last_bar_code >= fvl.bar_code
WHERE YEAR(fvl.created_on) = ?
AND MONTH(fvl.created_on) = ?
GROUP BY fvl.bar_code
) ni
ON ni.bar_code = fvll.bar_code
WHERE YEAR(fvll.created_on) = ?
AND MONTH(fvll.created_on) = ?
GROUP
BY user.first_name AS prenom
, user.last_name AS nom
, fvll.created_on
, fvll.bar_code
, CASE WHEN ni.bar_code IS NULL THEN 'R' ELSE 'B' END
ORDER
BY fv11.created_on
子句。
对于日期比较,我选择比较原始日期,因此查询可以有效地使用索引范围扫描操作。
而不是:
GROUP BY
我会写类似
的内容 WHERE YEAR(fvll.created_on) = ?
AND MONTH(fvll.created_on) = ?
WHERE fvll.created_on >= month_begin_dt + INTERVAL 0 MONTH
AND fvll.created_on >= month_begin_dt + INTERVAL 1 MONTH
表示返回该月第一天的表达式,但需要传入,如果我们需要构建一年和一个月的DATE,我们可以这样做。最终目标是等同于:
month_begin_dt