0

バックエンドデータベースを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ステートメントがないことです。誰かがフィードバックやアドバイスを提供することができれば、私はそれを大いに感謝します!

4

1 に答える 1

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

私はいくつかの構文を見逃していると確信していますが、うまくいけば、これで始められます。

于 2012-06-12T16:46:09.857 に答える