4

私はこのテーブルを持っています

ID値ユーザーストック
--|--------|---------|---------
  1 | 10 | マーク | AAPL
  2 | 20 | 奪う | グーグ
  3 | 30 | マーク | AAPL
  4 | -40 | マーク | AAPL
  5 | -10 | 奪う | グーグ
  6 | 25 | マーク | グーグ
  7 | 5 | マーク | グーグ
  8 | 45 | マーク | AAPL

以下に示す行を返すクエリを (おそらく PGSQL 関数を使用せずに) 作成したいと思います。ユーザー、株式でグループ化された「値」列を合計する順序 (ID ASC) で開始する必要があります。一時的な合計が 0 の場合、(そのグループの) 前の行はすべて破棄されます。

id値ユーザーストック
--|--------|---------|---------
  2 | 20 | 奪う | グーグ
  5 | -10 | 奪う | グーグ
  6 | 25 | マーク | グーグ
  7 | 5 | マーク | グーグ
  8 | 45 | マーク | AAPL

OVER(PARTITION BY)やWINDOW関数を使えばいいと思います SELECT *, SUM(value) OVER w AS scm FROM "mytable" WINDOW w AS (PARTITION BY user,stock ORDER BY id ASC)

これは次のテーブルを返します

ID値ユーザーストックscm
----|--------|---------|---------|-------
  1 | 10 | マーク | AAPL | AAPL | 10
  2 | 20 | 奪う | グーグ | 20
  3 | 30 | マーク | AAPL | AAPL | 40
  4 | -40 | マーク | AAPL | AAPL | 0
  5 | -10 | 奪う | グーグ | 10
  6 | 25 | マーク | グーグ | 25
  7 | 5 | マーク | グーグ | 30
  8 | 45 | マーク | AAPL | AAPL | 45

これは、マークの APPL が 0 (id=4) であり、そのグループ (AAPL,mark) の次のすべての行を保持する必要があることを示しているため、良い出発点になるはずです。ルールは次のとおりです。各グループ (在庫、ユーザー) について、scm=0 の最後の行に続くすべての行を保持します。

4

2 に答える 2

1

SQL Fiddle

with s as (
    select *,
        count(scm = 0 or null) over w z
    from (
        select *,
            sum(value) over w as scm
        from mytable
        window w as (partition by "user", stock order by id asc)
    ) s
    window w as (partition by "user", stock order by id asc)
)
select *
from
    s
    inner join
    (
        select max(z) z, "user", stock
        from s
        group by "user", stock
    ) z using (z, "user", stock)
where scm > 0
order by s.user, s.stock, id
于 2013-04-17T16:00:31.493 に答える
0

次のようなものは、あなたが望むようになると思います。基本的には以下を実行します。

  1. 累積合計を計算するために必要な SQL ステートメントを使用します。
  2. (username, stock)各グループに表示する必要がある最小 ID を計算します。
  3. 元の SQL 累積合計から選択し、最小 ID よりも小さい ID を除外します。
WITH sums AS (
  SELECT id, value, username, stock, SUM(value) OVER w AS scm
    FROM "mytable"
  WINDOW w AS (PARTITION BY user,stock ORDER BY id ASC)),

minimum_ids AS (
  SELECT username, stock, MAX(id) as minimum_id
    FROM sums
   WHERE scm <= 0
   GROUP BY username, stock)

SELECT sums.id, sums.value, sums.username, sums.stock, sums.scm
  FROM sums
  LEFT JOIN minimum_ids
    ON (sums.username = minimum_ids.username
        AND sums.stock = minimum_ids.stock)
 WHERE (minimum_ids.minimum_id IS NULL OR sums.id > minimum_ids.minimum_id)
 ORDER BY id;
于 2013-04-17T15:59:03.620 に答える