webdevqa.jp.net

Oracle SQLクエリ:時間に基づいてグループごとに最新の値を取得します

OracleDBに次のテーブルがあります

id     date              quantity
1      2010-01-04 11:00  152
2      2010-01-04 11:00  210
1      2010-01-04 10:45  132
2      2010-01-04 10:45  318
4      2010-01-04 10:45  122
1      2010-01-04 10:30  1
3      2010-01-04 10:30  214
2      2010-01-04 10:30  5515
4      2010-01-04 10:30  210

ここで、IDごとに最新の値(およびその時刻)を取得したいと思います。出力例:

id     date              quantity
1      2010-01-04 11:00  152
2      2010-01-04 11:00  210
3      2010-01-04 10:30  214
4      2010-01-04 10:45  122

それをクエリに入れる方法がわかりません...

さらに、次のオプションが最適です。

オプション1:クエリは過去XX分からの値のみを返す必要があります。

オプション2:idは、idとidnameを持つ別のテーブルのテキストと連結する必要があります。 idの出力は次のようになります:id-idname(例:1-testid1)。

助けてくれてありがとう!

16
Tom

このデータを考えると...

SQL> select * from qtys
  2  /

        ID TS                      QTY
---------- ---------------- ----------
         1 2010-01-04 11:00        152
         2 2010-01-04 11:00        210
         1 2010-01-04 10:45        132
         2 2010-01-04 10:45        318
         4 2010-01-04 10:45        122
         1 2010-01-04 10:30          1
         3 2010-01-04 10:30        214
         2 2010-01-04 10:30       5515
         4 2010-01-04 10:30        210

9 rows selected.

SQL>

...次のクエリはあなたが望むものを与えます...

SQL> select x.id
  2         , x.ts as "DATE"
  3         , x.qty as "QUANTITY"
  4  from (
  5      select id
  6             , ts
  7             , rank () over (partition by id order by ts desc) as rnk
  8             , qty
  9      from qtys ) x
 10  where x.rnk = 1
 11  /

        ID DATE               QUANTITY
---------- ---------------- ----------
         1 2010-01-04 11:00        152
         2 2010-01-04 11:00        210
         3 2010-01-04 10:30        214
         4 2010-01-04 10:45        122

SQL>

追加の要件に関しては、外側のWHERE句に追加のフィルターを適用できます。同様に、他のテーブルと同じように、追加のテーブルをインラインビューに結合できます。

24
APC

これが完全なテスト済みの例です。

CREATE TABLE tbl1 (ID NUMBER, dt DATE, quantity NUMBER);

DELETE FROM tbl1;
insert into tbl1 values (1,to_date('2010-01-04 11:00','YYYY-MM-DD HH24:MI'), 152);
insert into tbl1 values (2,to_date('2010-01-04 11:00','YYYY-MM-DD HH24:MI'), 210);
insert into tbl1 values (1,to_date('2010-01-04 10:45','YYYY-MM-DD HH24:MI'), 132);
insert into tbl1 values (2,to_date('2010-01-04 10:45','YYYY-MM-DD HH24:MI'), 318);
insert into tbl1 values (4,to_date('2010-01-04 10:45','YYYY-MM-DD HH24:MI'), 122);
insert into tbl1 values (1,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 1);
insert into tbl1 values (3,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 214);
insert into tbl1 values (2,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 5515);
insert into tbl1 values (4,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 210);

SELECT t.ID
     , t.DT
     , t.QUANTITY
  FROM tbl1 t
     ,( SELECT ID
             , MAX(dt) dt
          FROM tbl1
       GROUP BY ID ) t2
  WHERE t.id = t2.id
    AND t.dt = t2.dt

結果:

1   1/4/2010 11:00:00 AM    152
2   1/4/2010 11:00:00 AM    210
3   1/4/2010 10:30:00 AM    214
4   1/4/2010 10:45:00 AM    122

過去XX分間のレコードを取得する場合は、これを行うことができます(この例では、500分を使用していますが、500を任意のものに置き換えます)。

   SELECT t.ID
        , t.DT
        , t.QUANTITY
     FROM tbl1 t
        ,( SELECT ID
                , MAX(dt) dt
             FROM tbl1
            WHERE dt >= SYSDATE - (500 / 1400)
          GROUP BY ID ) t2
     WHERE t.id = t2.id
       AND t.dt = t2.dt;
8
dcp