仅在下一行与上一行不同时计数

时间:2019-08-08 09:01:40

标签: sql oracle count analytic-functions

我有一个包含12个寄存器的表。我想对行进行计数,即使列“ AREA_OPERATIVA”与上一行不同(按日期升序排列)。

table

例如,从第1行到第2行,它不应该计数任何东西,因为它们都具有相同的“ CROSS”区域,但是在第2行和第3行之间,它应该计数(或总和1,我不在乎),因为”和“ UTRDANIOS”不同。因此,整个表的最终计数应为3。

是否可以通过查询来执行此操作,或者我是否需要为此编写带有光标的脚本?

我已经尝试过了:

SELECT  a.creclama, 
sum (CASE WHEN b.area_operativa  NOT LIKE  a.area_operativa THEN 1 ELSE 0 END) AS increment
FROM TR_ASGAREOPE a
INNER JOIN TR_ASGAREOPE b ON a.creclama = b.creclama 
                          and a.cdistribuidora = b.cdistribuidora 
                          and a.secuencia = b.secuencia
WHERE a.creclama = 10008354
group by a.creclama;

但是正在计算完整的12行。

编辑:

最后我可以通过下一个查询解决此问题:

select sum (
    CASE WHEN (comparacion.area_operativa  not like  comparacion.siguiente_fila THEN 1 ELSE 0 END) AS incremento 
from (    
    select creclama,
           area_operativa, 
           lead(area_operativa) over (order by fmodifica) as siguiente_fila
    from TR_ASGAREOPE
    where creclama = 10008354
    order by fmodifica
);

希望以后对某人有用,这真的让我呆了一天。谢谢大家。

4 个答案:

答案 0 :(得分:4)

例如,您可以尝试使用超前或滞后等分析功能

    SELECT CRECLAMA,
           CASE WHEN AREA_OPERATIVA <> NEXTROW THEN 1 ELSE 0 END AS INCREMENT
      FROM (
            SELECT CRECLAMA,
                   AREA_OPERATIVA,
                   LEAD(AREA_OPERATIVA) OVER (PARTITION BY 1 ORDER BY CRECLAMA) AS NEXTROW
              FROM TR_ASGAREOPE
            )

答案 1 :(得分:1)

您可以使用lag()分析函数:

with t as
(
 select a.*,
        lag(a.area_operativa,1,a.area_operativa) over (order by a."date") as lg
   from asgareope a
  where a.creclama = 10008354
)   
select t.creclama, sum(case when lg = area_operativa then 0 else 1 end) as "increment"
  from t     
 group by t.creclama

答案 2 :(得分:1)

以下是使用LEAD的一种方法:

WITH TR_ASGAREOPE(CRECLAMA, AREA_OPERATIVA, DATE_FIELD) AS
                 (SELECT 10008354, 'CROSS', DATE '2019-01-01' FROM DUAL UNION ALL
                  SELECT 10008354, 'CROSS', DATE '2019-01-02' FROM DUAL UNION ALL      -- 1
                  SELECT 10008354, 'UTRDANIOS', DATE '2019-01-03' FROM DUAL UNION ALL  -- 2
                  SELECT 10008354, 'EXP263', DATE '2019-01-04' FROM DUAL UNION ALL     -- 3
                  SELECT 10008354, 'EXP6', DATE '2019-01-05' FROM DUAL UNION ALL
                  SELECT 10008354, 'EXP6', DATE '2019-01-06' FROM DUAL UNION ALL
                  SELECT 10008354, 'EXP6', DATE '2019-01-07' FROM DUAL UNION ALL
                  SELECT 10008354, 'EXP6', DATE '2019-01-08' FROM DUAL UNION ALL
                  SELECT 10008354, 'EXP6', DATE '2019-01-09' FROM DUAL UNION ALL
                  SELECT 10008354, 'EXP6', DATE '2019-01-10' FROM DUAL UNION ALL
                  SELECT 10008354, 'EXP6', DATE '2019-01-11' FROM DUAL UNION ALL
                  SELECT 10008354, 'EXP6', DATE '2019-01-12' FROM DUAL UNION ALL
                  SELECT 12345678, 'AREA49', DATE '2019-02-01' FROM DUAL UNION ALL
                  SELECT 12345678, 'AREA49', DATE '2019-02-02' FROM DUAL UNION ALL  -- 1
                  SELECT 12345678, 'AREA50', DATE '2019-02-03' FROM DUAL UNION ALL
                  SELECT 12345678, 'AREA50', DATE '2019-02-04' FROM DUAL UNION ALL  -- 2
                  SELECT 12345678, 'AREA52', DATE '2019-02-05' FROM DUAL UNION ALL
                  SELECT 12345678, 'AREA52', DATE '2019-02-06' FROM DUAL UNION ALL
                  SELECT 12345678, 'AREA52', DATE '2019-02-07' FROM DUAL UNION ALL  -- 3
                  SELECT 12345678, 'AREA53', DATE '2019-02-08' FROM DUAL UNION ALL  -- 4
                  SELECT 12345678, 'AREA52', DATE '2019-02-09' FROM DUAL UNION ALL  -- 5
                  SELECT 12345678, 'AREA53', DATE '2019-02-10' FROM DUAL),
     cteData AS (SELECT CRECLAMA,
                         LEAD(CRECLAMA) OVER (ORDER BY DATE_FIELD) AS NEXT_CRECLAMA,
                         AREA_OPERATIVA,
                         LEAD(AREA_OPERATIVA) OVER (ORDER BY DATE_FIELD) AS NEXT_AREA_OPERATIVA
                    FROM TR_ASGAREOPE)
SELECT CRECLAMA, COUNT(*)
  FROM cteData
  WHERE CRECLAMA = NEXT_CRECLAMA AND
        AREA_OPERATIVA <> NEXT_AREA_OPERATIVA
  GROUP BY CRECLAMA
  ORDER BY CRECLAMA;

我为另一个CRECLAMA值添加了数据,以显示其工作原理。

结果:

CRECLAMA    COUNT(*)
10008354    3
12345678    5

dbfiddle here

答案 3 :(得分:0)

我认为如果COUNT(DISTINCT ...)无法恢复为先前使用的值,您可以简单地使用AREA_OPERATIVA

SELECT CRECLAMA, COUNT(DISTINCT AREA_OPERATIVA)
  FROM TR_ASGAREOPE
 GROUP BY CRECLAMA