2012-06-12 2 views
0

나는 우리의 백엔드 데이터베이스를 mysql에서 postgres로 옮기고 모든 이전 쿼리/함수를 마이그레이션하는 과정에있다. 그들 중 대부분은 하찮은 일이지만 오늘 나는 내 머리를 긁적 게하는 것을 가로 질렀다. 여기에 있습니다 :이상한 MySQL 쿼리를 group_concat을 사용하는 Postgresql로 바꾸기

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

'option_id','variable_id' 및'code_round_id' 열이 속한 테이블을 제공 할 수 있습니까? 그것들은'k_value'에 속해 있습니까? –

+0

option_id, variable_id 및 code_round_id가 k_value에 속합니다. –

+0

IF는 일반적으로 PostgreSQL (및 기타 표준 호환 SQL 데이터베이스)의 CASE로 변환됩니다. –

답변

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의 표현은 (그리고 PostgreSQL을에)

표준 SQL로 번역 될 수있는 방법을 보여줍니다 생각 내가 몇 가지 구문 일을 놓친 확실 해요, 그러나 희망이

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 

:이 옳은 일을하는 것 같다 일단, 나는 UPDATE 문에 그 포장 것 너 시작 했어.

+0

가장 우수한 쿼리로서 쿼리가 거의 효과가있었습니다. –