选择低于另一个的值 - Oracle

时间:2016-04-15 12:57:50

标签: sql oracle dense-rank

我有一张包含各种信息的表格,我需要选择以下值:

1)有cod_anag_prov = 0或= 2
2)具有计数(1)> 1

然后为每个与第1点和第2点相关的单个记录设置一个标志为1,并在所有事件中都有最小计数(1)。
我想到了使用dense_rank函数并编写了这个:

SELECT PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF,
   MAX_CNT,
    MIN(MAX_CNT) KEEP (DENSE_RANK FIRST ORDER BY MAX_CNT) OVER (PARTITION BY PDRA) OCCORRENZA_MINORE
    FROM 
    (SELECT PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF,
    COUNT(1) AS MAX_CNT
  FROM STM_VOLUME_AGGR
 WHERE (COD_ANAGR_PROV = 0
  OR COD_ANAGR_PROV    = 2)
   GROUP BY PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF
 HAVING COUNT(1)>1
  ORDER BY PDRA);



到目前为止(我认为)我已经能够做到我之前说的话。
现在,如果我有这样的结果:

    34624200    1905    201305  6   6
    34624200    83      201305  13  6
    34624200    93      201305  14  6
    34439201    1       201305  11  2
    34439201    6       201305  2   2

我希望将行的标志设置为1:

 34624200   1905    201305  6   6
 34439201   6       201305  2   2


我怎么能这样做?! 我知道我做的事情要复杂得多,但现在我的大脑正在融化xD(我对SQL很新)...

更新1: 好的,我已经完成了,但我当然需要优化它。费用为3.300.000:S

这是我的解决方案:

SELECT PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF,
   MIN(MAX_CNT),
    NUMERO_OCCORRENZE FROM
 (SELECT PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF,
   MAX_CNT,
    MIN(MAX_CNT) KEEP (DENSE_RANK FIRST ORDER BY MAX_CNT) OVER (PARTITION BY PDRA) NUMERO_OCCORRENZE
    FROM
    (SELECT PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF,
    COUNT(1) AS MAX_CNT
  FROM STM_VOLUME_AGGR
 WHERE (COD_ANAGR_PROV = 0
  OR COD_ANAGR_PROV    = 2)
   GROUP BY PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF
 HAVING COUNT(1)>1
  ORDER BY PDRA))
  GROUP BY 
  PDRA, COD_DISTRIBUTORE_STARGAS, ANNOMESE_RIF, NUMERO_OCCORRENZE
  HAVING MIN(MAX_CNT)=NUMERO_OCCORRENZE
  ;

显然我不确定这是最好的解决方案(即使有效)......

3 个答案:

答案 0 :(得分:0)

您的查询需要简化,但是, 快速获胜;

    SELECT PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF,
   MAX_CNT,
   row_number() over(partititon by PDRA order by MAX_CNT) rank_id
    FROM 
    (SELECT PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF,
    COUNT(1) AS MAX_CNT
  FROM STM_VOLUME_AGGR
 WHERE (COD_ANAGR_PROV = 0
  OR COD_ANAGR_PROV    = 2)
   GROUP BY PDRA,
    COD_DISTRIBUTORE_STARGAS,
    ANNOMESE_RIF
 HAVING COUNT(1)>1
  ORDER BY PDRA)

答案 1 :(得分:0)

如果我理解这种情况发生,当OCCORRENZA_MINORE = MAX_CNT:

UPDATE STM_VOLUME_AGGR
   SET flag = 1
 WHERE (PDRA, COD_DISTRIBUTORE_STARGAS, ANNOMESE_RIF) IN 
       (SELECT PDRA, COD_DISTRIBUTORE_STARGAS, ANNOMESE_RIF
          FROM ( your_query )
         WHERE OCCORRENZA_MINORE = MAX_CNT)
   AND (COD_ANAGR_PROV = 0 OR COD_ANAGR_PROV = 2)

答案 2 :(得分:0)

前面提到的一个组或另一个你通过" case"填充的列。以及查询的最后两列之间的比较(大小写等于1然后0结束)。