【问题标题】:Problem with a query in Postgres that I want to move to SQL Server我想移动到 SQL Server 的 Postgres 查询出现问题
【发布时间】:2019-03-02 18:44:11
【问题描述】:

我现在需要在 SQL Server 上运行的 postgres 中有以下查询。显然我已经改变了每轮的 trunc 和基本的东西,但主要是我在 (c.cod_socio) tbl 上选择 distinct 的原则上有问题。 * 因为 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 

【问题讨论】:

标签: sql sql-server


【解决方案1】:

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

【讨论】:

猜你喜欢
  • 2019-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多