2016-04-15 2 views
0

У меня есть таблица с различной информацией, и нужно выбрать значения, которые:

1) имеет cod_anag_prov = 0 или = 2
2) имеет счетчик (1)> 1

, а затем установите флаг для 1 для каждой и каждой записи, которая соответствует точкам 1 и 2, и имеет счетчик минут (1) среди всех вхождений.
Я думал использовать функцию DENSE_RANK и составил это:

Выберите значения ниже, чем другое - Oracle

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) ...


UPDATE 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 
    ; 



Очевидно, я не уверен, что это лучшее решение (даже если он работает) ...

+1

Что вы подразумеваете под "флагом"? Не возражаете ли вы размещать исходные данные образца, чтобы мы могли помочь вам лучше? Независимо - кажется, вам сейчас нужно использовать предложение GROUP BY (и выбрать max (col2), группу по другим столбцам). – mathguy

+0

Кроме того, почему тег plsql и ссылка в вашем вопросе? Это похоже на прямой SQL. – mathguy

+0

Да, я ошибся с тегом xD –

ответ

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) 
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) 
0

Либо группа по, как упоминалось ранее, или еще один столбец, который вы заполнить с помощью «дела» и сравнение между двумя последними столбцы вашего запроса (случай ... когда равно, а затем еще 1 конец 0).

Смежные вопросы