3

次の表が与えられた

  grp |   ind |   val
----------------------
    a |     1 |     1
    a |     2 |     1
    a |     3 |     1
    a |     4 |     2
    a |     5 |     2
    a |     6 |     4
    a |     7 |     2
    b |     1 |     1
    b |     2 |     1
    b |     3 |     1
    b |     4 |     3
    b |     5 |     3
    b |     6 |     4

以下を選択する必要があります。

  grp |   ind |   val
----------------------
    a |     1 |     1
    a |     4 |     2
    a |     6 |     4
    a |     7 |     2
    b |     1 |     1
    b |     4 |     3
    b |     6 |     4

つまり、「grp」ごとに、「val」が先行する「val」とは異なる各レコード(「index」の順序)です。したがって、「value」が「steps」である各レコード。

これを達成するための最も効率的な方法は何でしょうか?

ありがとう。

テストケースを作成するためのスクリプトは次のとおりです。

create temp table test_table
(
    grp character varying,
    ind numeric,
    val numeric
);
insert into test_table values
    ('a', 1 , 1),
    ('a', 2 , 1),
    ('a', 3 , 1),
    ('a', 4 , 2),
    ('a', 5 , 2),
    ('a', 6 , 4),
    ('a', 7 , 2),
    ('b', 1 , 1),
    ('b', 2 , 1),
    ('b', 3 , 1),
    ('b', 4 , 3),
    ('b', 5 , 3),
    ('b', 6 , 4);
4

3 に答える 3

2
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE ztable
        ( zgroup CHAR(1)
        , zindex int
        , zvalue INTEGER
        );
INSERT INTO ztable(zgroup,zindex,zvalue) VALUES
    ('a',     1,      1)
    ,('a',     2,      1)
    ,('a',     3,      1)
    ,('a',     4,      2)
    ,('a',     5,      2)
    ,('a',     6,      4)
    ,('b',     1,      1)
    ,('b',     2,      1)
    ,('b',     3,      1)
    ,('b',     4,      3)
    ,('b',     5,      3)
    ,('b',     6,      4)
        ;

WITH agg AS (
        SELECT zgroup
        , zindex
        , zvalue
        , row_number() OVER (PARTITION BY zgroup ORDER BY zindex) AS zrank
        FROM ztable
        )
SELECT t1.zgroup,t1.zindex,t1.zvalue
FROM agg t1
LEFT JOIN agg t0 ON t0.zgroup = t1.zgroup AND 1+t0.zrank = t1.zrank
WHERE t0.zvalue <> t1.zvalue OR t0.zrank IS NULL
        ;
于 2012-07-18T10:46:59.137 に答える
2
select grp,
       ind,
       val
from (
   select grp, 
          ind, 
          val,
          lag(val,1,0::numeric) over (partition by grp order by ind) - val as diff
   from test_table
) t
where diff <> 0;
于 2012-07-18T10:55:50.093 に答える
1
select group,min(index) as index,value from table
group by group,value
于 2012-07-18T10:31:26.577 に答える