Получить столбец, в котором отношение не равно NULL

У меня есть база данных, которая была перенесена с SQL Server на MySQL. У меня был существующий запрос в SQL Server, чтобы получить значение столбца, в котором отношение не равно нулю, я имею в виду, если отношение между двумя таблицами равно нулю, то это означает, что должна быть связь с другой таблицей.

Это запрос, который я использовал:

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?

2 ответа

Решение

У вас есть пара вопросов для рассмотрения:

1 - APPLY Оператор не поддерживается в MySQL. Тем не менее, для вашего данного использования, похоже, вы можете просто использовать LEFT OUTER JOIN,

2 - MySQL не поддерживает TOP, Вместо этого используйте LIMIT, Тем не менее, я не думаю, что вам нужно в этом случае, так как вы используете MIN каждого из этих полей.

3 - Чтобы объединить строки в MySQL, используйте CONCAT против "+",

4 - Наконец, я предпочитаю использовать COALESCE в MySQL, чтобы проверить NULLs, Есть и другие варианты.

Итак, все это вместе, это должно быть близко (не проверено):

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 

Вам могут не понадобиться некоторые из этих полей в вашем GROUP BY - только твой DISTINCT поля необходимы.

Я думаю, что это превращает его в действительный запрос 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 

Я заменил isnull() с coalesce() - если вы переходите между базами данных, по возможности используйте стандартный SQL. Я заменил + для объединения с concat_ws(), Обратите внимание, что есть небольшая разница.,, если одно из полей имеет значение NULL, то значение MySQL будет обрабатываться как ''.

Я заменил cross apply с совокупностью. Ты используешь top 1 без order by, так что это выбирает произвольную строку. Итак, эта версия произвольно выбирает максимальное значение.

Другие вопросы по тегам