Keresés

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

  • kojakhu

    újonc

    válasz bambano #5009 üzenetére

    Közben meg is írta h mi a pontos elvárás, de a kódolástól nem láttam :)

    Itt van, ami szerintem már helyes, csak azért h hátha meg lehet mégis csinálni.

    Viszont performancia miatt nem lesz használható.
    Max akkor, ha valahogy a sorok számát a rekurzív részben lehet limitálni. Pl ha lehet tudni, hogy max mekkora gapek vannak a logok között (ezt is ki lehet számolni akár), vagy esetleg az előző munkámmal lehet összeszerelni úgy h az ott előálló csoportokban kell csak részcsoportokat képezni.

    Szóval brahiból itt az újabb SQLFiddle link
    Pls valaki mindenképpen válaszoljon (ha jó a megoldás, ha nem), mert a blogon "újoncként" nem írhatok csak 1-et amíg nincs rám válasz...

    Setup:
    create table t (dt timestamp);
    -- group 1
    insert into t values (current_timestamp);
    insert into t values (current_timestamp + interval '10' second);
    insert into t values (current_timestamp + interval '59' second);
    -- group 2
    insert into t values (current_timestamp + interval '70' second);
    insert into t values (current_timestamp + interval '71' second);
    insert into t values (current_timestamp + interval '129' second);
    -- group 3
    insert into t values (current_timestamp + interval '200' second);
    insert into t values (current_timestamp + interval '210' second);
    insert into t values (current_timestamp + interval '220' second);
    insert into t values (current_timestamp + interval '259' second);
    -- group 4
    insert into t values (current_timestamp + interval '260' second);
    insert into t values (current_timestamp + interval '261' second);

    Lekérdezés:
    WITH RECURSIVE rd(grp, mindt) AS (
    SELECT 1 AS grp
    , MIN(dt)
    FROM t
    UNION
    SELECT rd.grp+1 AS grp
    , FIRST_VALUE(t.dt) OVER (ORDER BY t.dt)
    FROM t, rd
    WHERE t.dt >= rd.mindt + INTERVAL '1' MINUTE
    ) -- rd
    , grpd AS (
    SELECT grp
    , t.*
    , MIN(dt) OVER (PARTITION BY grp) mindt
    , MAX(dt) OVER (PARTITION BY grp) maxdt
    , COUNT(*) OVER (PARTITION BY grp) cnt
    FROM rd, t
    WHERE t.dt >= rd.mindt AND t.dt < rd.mindt + INTERVAL '1' MINUTE
    ) -- grpd
    SELECT v.*
    , maxdt-mindt AS grp_duration
    FROM grpd AS v
    ORDER BY dt

  • kojakhu

    újonc

    válasz kw3v865 #4995 üzenetére

    Hali, Lehet erre gondolsz. Addig egy entry egy csoport, amíg a timestamp gap nagyobb nem lesz mint 1 perc. Csoportokban meg lehet N db entry is amíg a gap nem túl nagy.

    Ezt így lehet, pl.
    Itt az SQLFiddle : [link]

    Kód:

    Setup:

    create table t (dt timestamp);
    -- group 1
    insert into t values (current_timestamp - interval '10' second);
    insert into t values (current_timestamp);
    insert into t values (current_timestamp + interval '10' second);
    -- group 2
    insert into t values (current_timestamp + interval '120' second);
    insert into t values (current_timestamp + interval '130' second);
    -- group 3
    insert into t values (current_timestamp + interval '220' second);
    insert into t values (current_timestamp + interval '230' second);
    Lekérdezés:

    WITH
    diffs AS (
    SELECT dt
    , LAG(dt) OVER (ORDER BY dt) AS prevdt
    , LEAD(dt) OVER (ORDER BY dt) AS nextdt
    , ROW_NUMBER() OVER (ORDER BY dt) AS rn
    FROM t
    ) -- diffs
    , group_gaps_and_flags AS (
    SELECT v.*
    , dt-prevdt AS prev_gap
    , CASE WHEN prevdt IS NULL OR dt-prevdt > interval '1' minute
    THEN 'Y'
    END AS group_start_flag
    , nextdt - dt AS next_gap
    , CASE WHEN nextdt IS NULL OR nextdt-dt > interval '1' minute
    THEN 'Y'
    END AS group_end_flag
    , CASE WHEN prevdt IS NULL OR dt-prevdt > interval '1' minute
    THEN rn
    END AS rn_if_start
    FROM diffs AS v
    ) -- gaps_and_groups
    , groups AS (
    SELECT v.*
    , MAX(rn_if_start) OVER (ORDER BY dt) -- ROWS BETWEEN UNBOUNDED_PRECEEDING AND CURRENT_ROW
    AS my_group
    FROM group_gaps_and_flags AS v
    ) -- groups
    -- .
    -- SELECT * FROM groups; -- separator for testing
    -- .
    SELECT my_group, MIN(dt), MAX(dt), COUNT(dt)
    FROM groups
    GROUP BY my_group
    ORDER BY my_group


    sorry, nem tudom még ezen a fórumon hogy kell kódot beszúrni jól...

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