获取关系不为NULL的列

时间:2013-04-03 00:09:24

标签: mysql sql-server-2008 code-translation

我有一个从SQL Server迁移到MySQL的数据库。我在SQL Server中有一个现有的查询来获取关系不为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 APPLYISNULL。如何将此查询转换为MySQL?

2 个答案:

答案 0 :(得分:1)

您需要审核几个问题:

1 - MySQL不支持APPLY运算符。但是,对于您的使用情况,您似乎可以使用LEFT OUTER JOIN

2 - MySQL不支持TOP。相反,请使用LIMIT。但是,在这种情况下,我认为您不需要它,因为您使用的是每个字段的MIN

3 - 要在MySQL中连接字符串,请使用CONCAT vs "+"

4 - 最后,我更喜欢在MySQL中使用COALESCE来检查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字段。

答案 1 :(得分: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 

我将isnull()替换为coalesce() - 如果要在数据库之间进行,请尽可能使用标准SQL。我将+替换为concat_ws()以进行连接。注意有一点不同。 。 。如果其中一个字段为NULL,则MySQL值将其视为''。

我用聚合替换了cross apply。您使用top 1而没有order by,因此这将获取任意行。所以,这个版本随意选择最大值。