2016-04-15 7 views
0

Ich habe eine Tabelle mit verschiedenen Informationen und ich brauche die Werte auszuwählen, die:

1) cod_anag_prov haben = 0 oder = 2
2) eine Zählung (1)> 1

und setzen Sie dann für jeden einzelnen Datensatz, der Punkt 1 und 2 berücksichtigt, eine Markierung auf 1, und hat die Mindestanzahl (1) unter allen Vorkommen.
Ich dachte, die DENSE_RANK-Funktion verwenden und dies aus:

Wählen Sie Werte niedriger als ein anderer - 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); 



Bisher (glaube ich) Ich habe in der Lage zu tun, was ich vorhin gesagt hat. Jetzt
, wenn ich Ergebnisse wie diese:

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 



und ich möchte das Flag auf 1 für die Zeilen setzen:

34624200 1905 201305 6 6 
34439201 6  201305 2 2 



wie könnte ich das tun? !
Ich weiß, ich habe etwas getan, das weitaus komplexer ist, aber jetzt ist mein Gehirn xD schmelzen (Ich bin ziemlich neu in SQL) ...


UPDATE 1: Ok Ich habe es getan, aber sicher Ich muss es optimieren. Die Kosten betragen 3.300.000: S

Das ist meine Lösung ist:

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 
    ; 



Offensichtlich bin ich nicht sicher, dass dies die beste Lösung (auch wenn es funktioniert) ...

+1

Was meinst du mit "Flagge"? Haben Sie etwas dagegen, Beispieldaten einzugeben, damit wir Ihnen besser helfen können? Unabhängig davon - es scheint alles, was Sie gerade brauchen, ist eine GROUP BY-Klausel (und wählen Sie max (col2), Gruppe von den anderen Spalten). – mathguy

+0

Warum auch das Plsql-Tag und Referenz in Ihrer Frage? Dies scheint alles wie SQL zu sein. – mathguy

+0

yeah Ich habe einen Fehler mit dem Tag xD gemacht –

Antwort

0

Ihre Abfrage muss vereinfacht werden, aber Quick Win ist;

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

Wenn ich verstehe, dies geschieht, wenn 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

Entweder eine Gruppe wie bereits erwähnt oder eine andere Spalte, die Sie über „Fall“ zu füllen und einen Vergleich zwischen den beiden letzten Spalten Ihrer Anfrage (case ... wenn gleich dann 1 else 0 endet).