Frage

Ich mag eine einfache Abfrage auf einer Liste der Mitglieder treffen, die von einer Reihe und Gruppe sie in ‚Eimer‘ von gleicher Größe indiziert sind. So ist die Basis Abfrage ist:

select my_members.member_index from my_members where my_members.active=1;

Sag ich 1000 Mitglied Indexzahlen zurück, jetzt will ich sie in 10 gleich große Gruppen von max und min Mitglied Index aufzuspalten. So etwas wie:

Aktive Mitglieder in 0 bis 400: 100  Aktive Mitglieder in 401 bis 577: 100  ...  Aktive Mitglieder in 1584 bis 1765: 100

Das Beste, was ich tun konnte für den max (my_members.member_index) mit einer zunehmenden rownum Grenze wiederholt Abfrage:

  for r in 1 .. 10 loop
  select max(my_members.member_index)
  into ranges(r)
  from my_members
   where  my_members.active = 1
   and rownum < top_row
   order by my_members.member_index asc;
   top_row    := top_row + 100;
  end loop;
War es hilfreich?

Lösung

NTILE ist der Weg zu gehen -. Wert auf analytische Funktionen zu lesen, als sie Ihre SQL enorm vereinfachen

Kleinen Kommentar auf der Original-Code - dabei eine rownum Einschränkung vor eine ORDER BY-negative Ergebnisse führen kann,

for r in 1 .. 10 loop
   select max(my_members.member_index)
   into ranges(r)
   from my_members
   where  my_members.active = 1
   and rownum < top_row
   order by my_members.member_index asc;
   top_row    := top_row + 100;

Endschleife;

Versuchen Sie Folgendes:

create table example_nums (numval number)

begin
    for i in 1..100 loop
        insert into example_nums values (i);
   end loop;
end;

SELECT numval FROM example_nums 
WHERE rownum < 5 
ORDER BY numval DESC;

Um das gewünschte Ergebnis erwarten Sie tun müssen, um

SELECT numval FROM
   (SELECT numval FROM example_nums 
   ORDER BY numval DESC)
WHERE rownum < 5 

(Hinweis - hinter den Kulissen, Oracle diese in eine effiziente Art übersetzen wird, die immer nur hält die ‚Top 4 Artikel‘)

.

Andere Tipps

Es ist einfach und viel schneller die NTILE analytische Funktion mit:

SELECT member_index, NTILE(10) OVER (ORDER BY member_index) FROM my_members;

Oracle 10g Dokumentation: „NTILE eine analytische Funktion Er teilt gesetzt ein geordnete Daten in eine Anzahl von Buckets durch expr angegeben und weist die entsprechende bucket Nummer, die jede Zeile, um die Eimer 1 bis expr nummeriert sind...“

Danke für die Hilfe. Es dauerte eine Weile, es in einer Erklärung alle arbeiten (aus bestimmten Gründen, die auch ein Ziel war), so ist hier, was ich kam mit, dass sieht aus wie es funktioniert für mich:

select max(member_index), ranger
  from (SELECT member_index,
                    CASE
                        WHEN rownum < sized THEN 1
                        WHEN rownum < sized*2 THEN 2
                        WHEN rownum < sized*3 THEN 3
                        WHEN rownum < sized*4 THEN 4
                        WHEN rownum < sized*5 THEN 5
                        WHEN rownum < sized*6 THEN 6
                        WHEN rownum < sized*7 THEN 7
                        WHEN rownum < sized*8 THEN 8
                        WHEN rownum < sized*9 THEN 9
                        ELSE 10
                     END ranger
             from my_members,
                    (select count(*) / 10 sized
                        from my_members
                      where active = 1)
            where active = 1
            order by member_index)
 group by ranger;

Geben Sie mir meine Ergebnisse wie folgt aus:

member_index    ranger
2297683     1
2307055     2
2325667     3
2334819     4
2343982     5
2353325     6
2362247     7
6229146     8
8189767     9
26347329        10

Werfen Sie einen Blick auf der CASE-Anweisung in SQL und stellen Sie ein Gruppenfeld die Bereiche basierend off Sie wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top