我正在将我们的后端数据库从mysql移动到postgres,我正在迁移所有旧的查询/函数。他们中的大多数都是微不足道的,但是今天我遇到了一个让我摸不着头脑的人。这是:
UPDATE
k_coderound AS cr, k_coderound AS cr_m
SET
cr.is_correct = IF(
(SELECT GROUP_CONCAT(option_id ORDER BY variable_id) AS `values` FROM k_value
WHERE code_round_id=cr.id GROUP BY code_round_id) =
(SELECT GROUP_CONCAT(option_id ORDER BY variable_id) AS `values` FROM k_value
WHERE code_round_id=cr_m.id GROUP BY code_round_id),
1,
0
)
WHERE
cr.is_master=0
AND cr_m.is_master=1
AND cr_m.object_id=cr.object_id
AND cr_m.content_type_id =cr.content_type_id
我知道Postgres没有group_concat,而应该使用array_agg。我的问题是,我无法弄清楚究竟发生了什么 - 这个查询是很久以前由不再和我们在一起的人写的。同样困难的是Postgres缺乏IF声明。如果有人能够提供反馈或建议,我会非常感激!
答案 0 :(得分:1)
很难说出目的是什么。我的方法是首先找到一个返回“目标”数据的SELECT语句。
这样的事情:
select cr.is_correct,
array_agg(case when kv1.code_round_id = cr.id then kv1.option_id else null end, ',' order by kv1.variable_id) as kv_values1,
array_agg(case when kv2.code_round_id = cr_m.id then kv2.option_id else null end, ',' order by kv2.variable_id) as kv_values2
from k_coderound cr
join k_value kv1 on kv1.code_round_id = cr.id
join k_coderound cr_m
on cr_m.object_id=cr.object_id
and cr_m.content_type_id =cr.content_type_id
join k_value kv2 on kv2.code_round_id = cr_m.id
where cr.is_master=0
and cr_m.is_master=1
这很可能不正确,但我认为它显示了如何将非标准MySQL表达式转换为标准SQL(从而转换为PostgreSQL)
一旦这看起来做对了,我就把它包装到UPDATE语句中:
update k_coderound cru
set cr.is_correct = case
when t.kv_values1 = t.kv_values2 then 1
else 0
end
from (select cr.ctid,
array_agg(case when kv1.code_round_id = cr.id then kv1.option_id else null end, ',' order by kv1.variable_id) as kv_values1,
array_agg(case when kv2.code_round_id = cr_m.id then kv2.option_id else null end, ',' order by kv2.variable_id) as kv_values2
from k_coderound cr
join k_value kv1 on kv1.code_round_id = cr.id
join k_coderound cr_m
on cr_m.object_id=cr.object_id
and cr_m.content_type_id =cr.content_type_id
join k_value kv2 on kv2.code_round_id = cr_m.id
where cr.is_master=0
and cr_m.is_master=1
) t
where t.ctid = cru.ctid
我很确定我错过了一些语法问题,但希望这能让你开始。