2013-04-03 2 views
0

SQL Server에서 MySQL로 마이그레이션 된 데이터베이스가 있습니다. SQL Server에서 관계가 null이 아닌 열의 값을 얻으려는 기존 쿼리가있었습니다. 두 테이블 간의 관계가 null이면 다른 테이블과의 관계가 있어야 함을 의미합니다. 관계가 NULL이 아닌 열을 가져옵니다.

내가 사용하던 쿼리입니다 :

SELECT C.expediente, 
     C.status, 
     Sum(M.monto)        AS monto, 
     Sum(M.interes)       AS interes, 
     Sum(M.iva)        AS iva, 
     Sum(M.capital)       AS capital, 
     M.fecha_mov, 
     AB.tipo_abono, 
     AB.id_deposito, 
     Isnull(Min(tg.nombre), Min(tp.nombcomp)) AS nombreGrupo 
FROM movimientos AS M 
     JOIN acreditados AS A 
     ON A.id_acreditado = M.id_acreditado 
     JOIN creditos AS C 
     ON C.id_credito = A.id_credito 
     JOIN abonos AS AB 
     ON AB.id_movimiento = M.id_movimiento 
     OUTER apply (SELECT TOP 1 G.nombre 
        FROM grupos G 
        WHERE G.id_credito = C.id_credito) tg 
     OUTER apply (SELECT TOP 1 P.nombres + ' ' + P.apellido_paterno + ' ' 
           + P.apellido_materno AS NombComp 
        FROM personas P 
        WHERE A.id_persona = P.id_persona) tp 
GROUP BY M.fecha_mov, 
      AB.tipo_abono, 
      AB.id_deposito, 
      C.expediente, 
      C.status 
ORDER BY M.fecha_mov 

그러나 MySQL은 OUTER APPLY 또는 ISNULL 더이없는 것 같다. 어떻게이 쿼리를 MySQL로 변환 할 수 있습니까?

+0

OUTER APPLY에 대해 너무 확신하지는 않지만 ISNULL에 대해 IS NULL (공백 포함)을 사용해 보셨습니까? – Infiltrator

+0

mysql IS NULL은 하나의 표현식 만 평가하고, COALESCE 함수는 트릭을하지만, 여전히 Outer Apply 부분에 붙어 있습니다. –

+0

질문, 당신은'grupos'와'personas' 테이블에서 무엇을 얻고 있습니까? 각각'id_credito'와'id_persona'에 대해 무작위 레코드를 생성합니까? –

답변

1

당신은 문제의 몇 가지 검토해야 :

1 - APPLY 연산자는 MySQL을 지원하지 않습니다. 그러나 주어진 용도로는 LEFT OUTER JOIN을 사용할 수있는 것처럼 보입니다.

2 - MySQL은 TOP을 지원하지 않습니다. 대신 LIMIT을 사용하십시오. 그러나이 필드의 각각 MIN을 사용하고 있으므로이 경우에는 필요하지 않다고 생각합니다.

3 - MySQL에서 문자열을 연결하려면 CONCAT"+"을 사용하십시오.

4 - 마지막으로 NULLs을 확인하기 위해 MySQL에서 COALESCE을 사용하는 것을 선호합니다. 그러나 다른 옵션이 있습니다.

그래서 모두 함께 퍼팅이 가까이 (테스트되지 않은)해야한다 : 당신은 당신의 GROUP BY에서 이러한 필드의 일부를 필요로하지 않을 수 있습니다

SELECT C.expediente, 
     C.status, 
     Sum(M.monto)        AS monto, 
     Sum(M.interes)       AS interes, 
     Sum(M.iva)        AS iva, 
     Sum(M.capital)       AS capital, 
     M.fecha_mov, 
     AB.tipo_abono, 
     AB.id_deposito, 
     COALESCE(MIN(tg.nombre), MIN(tp.nombcomp)) AS nombreGrupo 
FROM movimientos AS M 
     JOIN acreditados AS A 
     ON A.id_acreditado = M.id_acreditado 
     JOIN creditos AS C 
     ON C.id_credito = A.id_credito 
     JOIN abonos AS AB 
     ON AB.id_movimiento = M.id_movimiento 
     LEFT OUTER JOIN (
      SELECT id_credito, nombre 
      FROM grupos 
      ) tg ON tg.id_credito = C.id_credito 
     LEFT OUTER JOIN (
      SELECT id_persona, CONCAT(nombres,' ',apellido_paterno,' ',apellido_materno) AS NombComp 
      FROM personas 
      ) tp ON A.id_persona = tp.id_persona 
GROUP BY M.fecha_mov, 
      AB.tipo_abono, 
      AB.id_deposito, 
      C.expediente, 
      C.status 
ORDER BY M.fecha_mov 

- 필요 당신의 DISTINCT 필드.

+0

완벽한 답변을 해주셔서 감사합니다. 쿼리를 테스트 해본 결과 작동했습니다. –

+0

@JorgeZapata - np, 기꺼이 도울 수있어! – sgeddes

1

나는이 유효한 MySQL의 쿼리로 바뀝니다 생각 :

SELECT C.expediente, C.status, Sum(M.monto) AS monto, Sum(M.interes) as interes, 
     Sum(M.iva) as iva, Sum(M.capital) as capital, 
     M.fecha_mov, AB.tipo_abono, AB.id_deposito, 
     coalesce(Min(tg.nombre), Min(tp.nombcomp)) AS nombreGrupo 
FROM movimientos M join 
     acreditados A 
     ON A.id_acreditado = M.id_acreditado join 
     creditos C 
     ON C.id_credito = A.id_credito join 
     abonos AB 
     ON AB.id_movimiento = M.id_movimiento join 
     (select g.id_credito, max(g.nombre) -- arbitrary nombre 
     from grupos g 
     group by g.id_credito 
     ) tg 
     on tG.id_credito = C.id_credito join 
     (SELECT P.id_persona, concat_ws(' ', P.nombres, P.apellido_paterno, P.apellido_materno) AS NombComp 
     FROM personas P 
     group by p.id_persona 
     ) tp 
     on A.id_persona = tP.id_persona 
GROUP BY M.fecha_mov, AB.tipo_abono, AB.id_deposito, C.expediente, C.status 
ORDER BY M.fecha_mov 

내가 coalesce()isnull() 교체 - 당신이 데이터베이스간에려고하는 경우에 가능한 표준 SQL을 사용합니다. 나는 concat_ws()으로 연결하기 위해 +을 바꿨다. 작은 차이가 있습니다. . . 필드 중 하나가 NULL이면 MySQL 값은 ''로 처리합니다.

cross apply을 집합체로 바꿨습니다. order by없이 top 1을 사용하므로 임의의 행을 가져옵니다. 따라서이 버전은 임의로 최대 값을 선택합니다.

+0

+1 SQL 표준 제시 –