我想移到SQL Server的Postgres中的查询问题

时间:2018-09-26 22:49:36

标签: sql sql-server

我在postgres中有以下查询,现在我需要在SQL Server上运行它。显然,我已经改变了每轮截断和基本的东西,但是主要是我在(c.cod_socio)tbl上选择不同的原则上有一个问题。 *由于SQL Server无法识别该语法。

select distinct on (c.cod_socio) 
    tbl.*, h.cod_oficina, h.cod_transaccion, h.num_transaccion, 
    h.num_sec, h.fec_movimiento
from 
    sgf_det_mov_his h 
inner join 
    sgf_cuenta c on c.cod_producto = h.cod_producto and c.cod_cuenta = h.cod_cuenta
inner join 
    sgf_tran t on t.cod_transaccion = h.cod_transaccion and t.cod_oficina = h.cod_oficina and t.cod_tipo_transaccion in ('DA', 'DP','NC') 
inner join 
    (select 
         sgf_cuenta.cod_socio, 
         sum(trunc(sgf_det_mov_his.val_efectivo, 0) + trunc(sgf_det_mov_his.val_cheques, 0)) as total 
     from 
         sgf_det_mov_his, sgf_cuenta, sgf_tran
     where 
         sgf_cuenta.cod_producto = sgf_det_mov_his.cod_producto
         and sgf_cuenta.cod_cuenta = sgf_det_mov_his.cod_cuenta
         and sgf_det_mov_his.sts_mov = 'A'
         and sgf_tran.cod_transaccion = sgf_det_mov_his.cod_transaccion
         and sgf_tran.cod_oficina = sgf_det_mov_his.cod_oficina
         and sgf_cuenta.cod_producto <> 2
         and sgf_tran.cod_tipo_transaccion in ('DA', 'DP','NC')
         and isnull(sgf_tran.cod_uaf, 0) > 0 
         and isnull(sgf_tran.cod_uaf, 0) not in (71)
         and sgf_cuenta.cod_cuenta not in (select cod_cuenta 
                                           from sgf_credito 
                                           where sgf_credito.cod_producto = sgf_cuenta.cod_producto
                                             and sgf_credito.cod_cuenta = sgf_cuenta.cod_cuenta
                                             and sts_operacion in ('A'))
         and date(sgf_det_mov_his.fec_movimiento) between '2015-01-01' and '2019-01-01'
     group by 
         sgf_cuenta.cod_socio
     having 
         sum(trunc(sgf_det_mov_his.val_efectivo,0) + trunc(sgf_det_mov_his.val_cheques,0)) >= 5000) tbl on tbl.cod_socio = c.cod_socio
where 
    date(h.fec_movimiento) between '2015-01-01' and '2019-01-01'
order by 
    c.cod_socio, h.fec_movimiento desc 

1 个答案:

答案 0 :(得分:0)

distinct on (...)仅保留可以使用row_number() over(...)和后面的where clause进行仿真的“第一行”,该谓词限制每个分区一个行。请注意,distinct on依靠order by子句来确定“第一行”,因此您需要over clause中的等效条件。还要注意,如果在两个数据库之间实现更大的查询兼容性之后,可以在PostgreSQL中使用相同的row_number方法。

SELECT
    *
FROM (
    SELECT
        ROW_NUMBER() OVER (PARTITION BY c.cod_socio ORDER BY h.fec_movimiento DESC) AS rn
      , c.cod_socio
      , tbl.*
      , h.cod_oficina
      , h.cod_transaccion
      , h.num_transaccion
      , h.num_sec
      , h.fec_movimiento
    FROM sgf_det_mov_his h
    INNER JOIN sgf_cuenta c ON c.cod_producto = h.cod_producto
        AND c.cod_cuenta = h.cod_cuenta
    INNER JOIN sgf_tran t ON t.cod_transaccion = h.cod_transaccion
        AND t.cod_oficina = h.cod_oficina
        AND t.cod_tipo_transaccion IN ('DA', 'DP', 'NC')
    INNER JOIN (
        SELECT
            sgf_cuenta.cod_socio
          , SUM(trunc(sgf_det_mov_his.val_efectivo, 0) + trunc(sgf_det_mov_his.val_cheques, 0)) AS total
        FROM sgf_det_mov_his
           , sgf_cuenta
           , sgf_tran
        WHERE sgf_cuenta.cod_producto = sgf_det_mov_his.cod_producto
        AND sgf_cuenta.cod_cuenta = sgf_det_mov_his.cod_cuenta
        AND sgf_det_mov_his.sts_mov = 'A'
        AND sgf_tran.cod_transaccion = sgf_det_mov_his.cod_transaccion
        AND sgf_tran.cod_oficina = sgf_det_mov_his.cod_oficina
        AND sgf_cuenta.cod_producto <> 2
        AND sgf_tran.cod_tipo_transaccion IN ('DA', 'DP', 'NC')
        AND ISNULL(sgf_tran.cod_uaf, 0) > 0
        AND ISNULL(sgf_tran.cod_uaf, 0) NOT IN (71)
        AND sgf_cuenta.cod_cuenta NOT IN (
            SELECT
                cod_cuenta
            FROM sgf_credito
            WHERE sgf_credito.cod_producto = sgf_cuenta.cod_producto
            AND sgf_credito.cod_cuenta = sgf_cuenta.cod_cuenta
            AND sts_operacion IN ('A')
        )
        AND DATE(sgf_det_mov_his.fec_movimiento) BETWEEN '2015-01-01' AND '2019-01-01'
        GROUP BY
            sgf_cuenta.cod_socio
        HAVING SUM(trunc(sgf_det_mov_his.val_efectivo, 0) + trunc(sgf_det_mov_his.val_cheques, 0)) >= 5000
    ) tbl ON tbl.cod_socio = c.cod_socio
    WHERE DATE(h.fec_movimiento) BETWEEN '2015-01-01' AND '2019-01-01'
) AS d
WHERE d.rn = 1
ORDER BY
    d.cod_socio
  , d.fec_movimiento DESC