Hirdetés

Új hozzászólás Aktív témák

  • nyunyu
    félisten

    Sziasztok!
    Top lekérdezéssel kapcsolatban lenne kérdésem: arra van módszer, hogy egy lekérdezésen belül visszakapjam az összesített és rendezett halmazból az első x elemet, valamint az ezeken kívüli rekordok összesített értékét is egy plusz sorban?
    Tehát pl. van egy táblám [A], [B] oszlopokkal és 1000 sorral, amikben az [A] 50 féle értéket vehet fel, a [B] pedig az aggregálandó mező. Ebből kellene pl. a TOP 5, de úgy, hogy gyakorlatilag 6 rekordot kapjak vissza: az utolsóban annak a 45 féle [A] értéknek az összesenjével, ami egyébként nem fért bele a topba.
    A nagyságrend elégé változó, de az [A] értékeket tekintve több 10e simán előfordulhat és a top is kb. tetszőleges, ezért kerülném a kétlépcsős megoldást (ha lehet).
    Firebird 2.5 és 3, MsSQL, Oracle megoldás érdekelne.

    Én kiemelném egy CTEbe az A, B összege oszlopokat, és kapna egy sorszámot összeg szerint csökkenő sorrendben, majd következő lépésben ebből válogatnám le a sorszám<=5-öt ("top 5"), és hozzáunióznám a szumma(B összeg)-et, ahol sorszám>5.

    Így az eredeti táblát csak egyszer kell végigolvasni, második lépésben uniót képző 2 select már a memóriában lévő párszáz-ezer soros aggregátumból dolgozik, minimális többletköltséggel.

    Valahogy így:
    with summa as (
    select a,
    sum(b) sum_b,
    row_number() over (partition by a order by sum(b) desc) rn
    from tabla5
    group by a),
    top5_summa as (
    select a,
    sum_b,
    rn
    from summa
    where rn<=5
    union
    select 'Többi' as a,
    sum(sum_b) as sum_b,
    6 as rn
    from summa
    where rn>5)

    select a,
    sum_b
    from top5_summa
    order by rn;

    Nem tudom, Firebird ismeri-e ezt a szintaxist, SQL Server kb. 2005 óta igen, meg az Oracle 11 alatt is működik.

Új hozzászólás Aktív témák