2017-07-21 1 views
0

更新されたbig oracle(Oracle Database 12c Enterprise Editionリリース12.1.0.2.0)表say table_nameがあります。 15秒ごとに それは多くの列が、私が懸念していたものを持っていることは、次のとおりです。各列の最大タイムスタンプを見つけて列の別の値を取得し、列の残りの部分を取得する方法

Name   Null? Type        
--------------- -------- --------------------------------- 
ID_1   NOT NULL NUMBER(38)       
UTC_TIMESTAMP NOT NULL TIMESTAMP(6) WITH TIME ZONE  
ID_2      VARCHAR2(8)      
SERVER_NAME    VARCHAR2(256)      
ID_3      NUMBER(38)       
COUNT_1     NUMBER(38)       
COUNT_2     NUMBER(38) 

私は何をしようとしていることである:

1)すべてのレコードを取得する場所UTC_TIMESTAMP < = CURRENT_DATEとUTC_TIMESTAMP> CURRENT_DATE - 5分(約125K-150K)

2)このデータはID_1が重複しています。だから私は、各ID_1が重複しているうちに最大(UTC_TIMESTAMP)を持つレコードだけを取りたいと思っています。だから今私たちは別のID_1を持っています。

私が試してみました何:を以下のSQL

with temp_1 as (
select m.ID_2, m.ID_1, max(utc_timestamp) max_utc_timestamp 
    from commsdesk.table_name m 
    where m.ID_2 = 'TWC' 
    group by m.ID_2, m.ID_1) 
select f.utc_timestamp 
    from commsdesk.table_name f 
    join temp_1 t 
    on t.max_utc_timestamp = f.utc_timestamp 
    and t.ID_2 = f.ID_2 
    and t.ID_1 = f.ID_1; 

問題の使用:を私はID_2、ID_1とUTC_TIMESTAMPを得ることができますが、私は同様に他のすべての列をしたいです。 SQLを使用して実行できますか?

5分のウィンドウ内に、約2200のID_1と約125K-150Kのレコードがあります。 これを行うには、Excelのシートに125K-150Kのレコードをコピーし、それぞれのID_1のUTC_TIMESTAMPの最大値を見つけるために2200 ID_1のそれぞれをフィルタリングすることで、非現実的です。 しかし、マクロを使ってすばやくそれをする方法があれば、それを行うこともできます。

サンプルダミーデータ:

ID_2 SERVER_NAME  ID_3 ID_1  UTC_TIMESTAMP    COUNT_1 COUNT_2 
ABC  PQRS.ABC.TPO 2  303  24-JUL-17 03.41.55.000000000 PM +00:00 4 0 
ABC  PQRS.ABC.TPO 2  1461  24-JUL-17 03.42.48.000000000 PM +00:00 1 7 
ABC  PQRS.ABC.TPO 2   1  24-JUL-17 03.41.36.000000000 PM +00:00 2 3 
ABC PQRS.ABC.TPO  2  1461  24-JUL-17 03.41.16.000000000 PM +00:00 0 8 
ABC PQRS.ABC.TPO  1   1  24-JUL-17 03.41.11.000000000 PM +00:00 5 0 
ABC SRP.ROP.MTP  1   1  24-JUL-17 03.41.23.000000000 PM +00:00 0 0 
ABC SRP.ROP.MTP  2  303  24-JUL-17 03.41.34.000000000 PM +00:00 0 0 
ABC SRP.ROP.MTP  2  1461  24-JUL-17 03.41.31.000000000 PM +00:00 0 0 
ABC SRP.ROP.MTP  4  303  24-JUL-17 03.41.26.000000000 PM +00:00 4 8 
ABC SRP.ROP.MTP  2  303  24-JUL-17 03.41.20.000000000 PM +00:00 0 0 
ABC SRP.ROP.MTP  1  1461  24-JUL-17 03.41.01.000000000 PM +00:00 3 8 
ABC SRP.ROP.MTP  4   1  24-JUL-17 03.41.18.000000000 PM +00:00 9 1 

予想される出力:

ID_1 UTC_TIMESTAMP       COUNT_1 COUNT_2 
1  24-JUL-17 03.41.36.000000000 PM +00:00 2  3 
303  24-JUL-17 03.41.55.000000000 PM +00:00 4  0 
1461 24-JUL-17 03.42.48.000000000 PM +00:00 1  7 
+0

サンプルデータには、説明したルールに基づいて重複がありません。いくつかの代表的なサンプルデータ*と*そのデータに期待する結果を示してください。 –

+0

サンプルデータを更新し、予想される出力を追加しました。応答が遅れて申し訳ありませんが、私は週末にデータにアクセスできませんでした。予想される出力が得られたら、MAX(UTC_TIMESTAMP)とSUM(COUNT_1)AND SUM(COUNT_2)を期待される出力から得るためにサブクエリとして使用します。 – 300

+0

最初に投稿したクエリはその結果を取得します。私はそれを表示するために私の答えを更新しました。私はあなたがサブクエリについて何を意味するか分かりません。あなたは最終的に '24-JUL-17 03.42.48'、7、10'で単一の結果を探していますか? –

答えて

2

あなたは(あなたが好む場合や、firstminmax()集約関数のthe keep (dense_rank last ...)バージョン、のようなものを使用することができます。

select id_1, 
    max(utc_timestamp), 
    max(id_2) keep (dense_rank last order by utc_timestamp) as id_2, 
    max(server_name) keep (dense_rank last order by utc_timestamp) as server_name, 
    max(id_3) keep (dense_rank last order by utc_timestamp) as id_3, 
    max(count_1) keep (dense_rank last order by utc_timestamp) as count_1, 
    max(count_2) keep (dense_rank last order by utc_timestamp) as count_2 
from table_name 
where utc_timestamp > current_timestamp - interval '5' minute 
and utc_timestamp <= current_timestamp 
group by id_1 
order by id_1; 

クエリはid_1でグループ化されています。最新のタイムスタンプが必要な場合は、max(utc_timestamp)は「通常」です。他の列は、id_の最大タイムスタンプを持つ行に関連付けられた値を保持します。いくつかのダミーデータで

insert into table_name (id_1, utc_timestamp, id_2, server_name, id_3, count_1, count_2) 
values (1, systimestamp at time zone 'UTC' - interval '30' second, 'TWC', 'test1', 301, 1, 1); 
insert into table_name (id_1, utc_timestamp, id_2, server_name, id_3, count_1, count_2) 
values (1, systimestamp at time zone 'UTC' - interval '60' second, 'TWC', 'test2', 302, 2, 2); 
insert into table_name (id_1, utc_timestamp, id_2, server_name, id_3, count_1, count_2) 
values (1, systimestamp at time zone 'UTC' - interval '90' second, 'TWC', 'test3', 303, 3, 3); 
insert into table_name (id_1, utc_timestamp, id_2, server_name, id_3, count_1, count_2) 
values (2, systimestamp at time zone 'UTC' - interval '45' second, 'TWC', 'test4', 304, 4, 4); 
insert into table_name (id_1, utc_timestamp, id_2, server_name, id_3, count_1, count_2) 
values (2, systimestamp at time zone 'UTC' - interval '15' second, 'TWC', 'test5', 305, 5, 5); 

そのクエリが結果を取得します。

 ID_1 MAX(UTC_TIMESTAMP)   ID_2  SERVE  ID_3 COUNT_1 COUNT_2 
---------- --------------------------- -------- ----- ---------- ---------- ---------- 
     1 2017-07-21 18:38:22.944 UTC TWC  test1  301   1   1 
     2 2017-07-21 18:38:38.399 UTC TWC  test5  305   5   5 

あなたはより多くのあなたの試みのようなものと同じ結果を得ることができます:

with cte as (
    select id_1, max(utc_timestamp) max_utc_timestamp 
    from table_name m 
    where utc_timestamp > current_timestamp - interval '5' minute 
    and utc_timestamp <= current_timestamp 
    group by id_1 
) 
select t.id_1, t.utc_timestamp, t.id_2, t.server_name, t.id_3, t.count_1, t.count_2 
from cte 
join table_name t on t.id_1 = cte.id_1 
and t.utc_timestamp = cte.max_utc_timestamp 
order by t.id_1; 

... 012とするとutc_timestampの組み合わせはユニークです(結合に​​を使用した理由は不明ですが、それは一意性のために必要なのでしょうか?)。しかし、実際のテーブルを2回クエリしなければならないので、効率が悪くなります。それぞれのテーブルの最大タイムスタンプを見つけてから、再度ジョインします。id_1結果とタイミング、実行計画を比較するには、おそらく両方のバージョンを実行する価値があります。あなたのサンプルデータで


(2017年7月24日に更新される)、上記の最初のクエリ - ちょうど合うように固定されたタイムスタンプの範囲を使用するように変更は - 取得:

 ID_1 MAX(UTC_TIMESTAMP)    ID_ SERVER_NAME  ID_3 COUNT_1 COUNT_2 
---------- --------------------------------- --- ------------ ---------- ---------- ---------- 
     1 2017-07-24 15:41:36.000000 +00:00 ABC PQRS.ABC.TPO   2   2   3 
     303 2017-07-24 15:41:55.000000 +00:00 ABC PQRS.ABC.TPO   2   4   0 
     1461 2017-07-24 15:42:48.000000 +00:00 ABC PQRS.ABC.TPO   2   1   7 

または取り出し列は、あなたがに興味があるように思えません。

select id_1, 
    max(utc_timestamp), 
    max(count_1) keep (dense_rank last order by utc_timestamp) as count_1, 
    max(count_2) keep (dense_rank last order by utc_timestamp) as count_2 
from table_name 
where utc_timestamp > timestamp '2017-07-24 16:40:00 Europe/London' -- current_timestamp - interval '5' minute 
and utc_timestamp <= timestamp '2017-07-24 16:45:00 Europe/London' -- current_timestamp 
group by id_1 
order by id_1; 

     ID_1 MAX(UTC_TIMESTAMP)     COUNT_1 COUNT_2 
---------- --------------------------------- ---------- ---------- 
     1 2017-07-24 15:41:36.000000 +00:00   2   3 
     303 2017-07-24 15:41:55.000000 +00:00   4   0 
     1461 2017-07-24 15:42:48.000000 +00:00   1   7 

そして、あなたの次のステップのために:

select max(max_utc_timestamp) as max_utc_timestamp, 
    sum(count_1) as sum_count_1, 
    sum(count_2) as sum_count_2 
from (
    select max(utc_timestamp) as max_utc_timestamp, 
    max(count_1) keep (dense_rank last order by utc_timestamp) as count_1, 
    max(count_2) keep (dense_rank last order by utc_timestamp) as count_2 
    from table_name 
    where utc_timestamp > timestamp '2017-07-24 16:40:00 Europe/London' -- current_timestamp - interval '5' minute 
    and utc_timestamp <= timestamp '2017-07-24 16:45:00 Europe/London' -- current_timestamp 
    group by id_1 
); 

MAX_UTC_TIMESTAMP     SUM_COUNT_1 SUM_COUNT_2 
--------------------------------- ----------- ----------- 
2017-07-24 15:42:48.000000 +00:00   7   10 
+0

あなたの返事ありがとうございました。私は私のポストでこれを言及していたはずです。 ID_1、ID_2、ID_3、SERVER_NAMEの組み合わせは一意です。あなたのSQLのバージョンを使用しようとしていて、それがどのようになっているかを教えてくれます。また、sum(count_1)とsum(count_2)を実行しています。ここでは大きな違いはありませんが、言いたいことがあります。 – 300

+0

@ 300 - 単純な集約ではありませんか? id_1/id_2/id_3/server_nameの固有の組み合わせごとに、最大タイムスタンプと両方の合計を求めますか? –

+0

いいえ、count_1とcount_2だけが合計したい実際の数値ですが、id_1、id_2、id_3は識別子です。 ID_2は、英数字のエントリを持つvarcharでもあります。ダミーのデータのサブセットを投稿しようとします。 – 300

関連する問題