2

ここで多くの回答を読みましたが、これが私の最初の質問です。私は初心者なので、質問のスタイル/形式に関する提案をいただければ幸いです。

PostgreSQL 9.1 events というテーブルが 1 つあります。primarykey=シリアルID

   ==============================================
   |serialid|             time|sender|dependency|

   |       1| 2012-11-22 14:40|  John|          |
   |       2| 2012-11-22 14:41|   Sue|         1|
   |       3| 2012-11-22 14:42|  John|         1|
   |       4| 2012-11-22 14:43|   Sue|          |
   |       5| 2012-11-22 14:44|  John|         4|
   |       6| 2012-11-22 14:44|  John|         4|

テーブルについて: 最初の行 (serialid==1) には 2 つの依存イベントがあります: 2nd、3rd

(1)最初の目標 WHERE ステートメントを作成した場合、例: WHERE sender="John" すべての依存イベントも結果テーブルに存在することを確認したいと思います。

悪い結果:

   |       1| 2012-11-22 14:40|  John|          |
   |       3| 2012-11-22 14:42|  John|         1|
   |       5| 2012-11-22 14:44|  John|         4|
   |       6| 2012-11-22 14:44|  John|         4|

John の「メイン イベント」に接続されているため、Sue のイベント (serialid==2) も必要です。

良い結果:

   |       1| 2012-11-22 14:40|  John|          |
   |       2| 2012-11-22 14:41|   Sue|         1|
   |       3| 2012-11-22 14:42|  John|         1|
   |       5| 2012-11-22 14:44|  John|         4|
   |       6| 2012-11-22 14:44|  John|         4|

(2) 2 番目の目標: 「良い結果」の表を見てみましょう。

   |       1| 2012-11-22 14:40|  John|          |
   |       2| 2012-11-22 14:41|   Sue|         1|
   |       3| 2012-11-22 14:42|  John|         1|
   |       5| 2012-11-22 14:44|  John|         4|
   |       6| 2012-11-22 14:44|  John|         4|

「メインイベント」のないイベントがあります。serialid: 5,6 のイベントは、イベント serialid: 4 に依存していますが、結果には含まれていません。良い結果は次のようになります。

   |       1| 2012-11-22 14:40|  John|          |
   |       2| 2012-11-22 14:41|   Sue|         1|
   |       3| 2012-11-22 14:42|  John|         1|
   |       4| 2012-11-22 14:43|   Sue|          |
   |       5| 2012-11-22 14:44|  John|         4|
   |       6| 2012-11-22 14:44|  John|         4|

(概要) したがって、カスタムの where ステートメントを指定できるクエリが必要であり、残りのクエリは where ステートメントの結果のすべての依存関係を収集します。

このようなもの:

SELECT * FROM イベント WHERE "私の条件"

連合??魔法の依存関係コレクター クエリ :-)

(注) 依存関係の深さは 1 レベルのみです。

前もってありがとう、デイブ

アップデート

Igor に感謝します。実際のデータベースで実際のクエリを取得しました。

WITH RECURSIVE dep_event AS 
(
  SELECT ev.serialid,ev.time_processed,ev.time_created,ev.sender_console,ev.sender_manager,ev.sender_map,ev.sender_device,ev.event_type,ev.event_command,ev.event_severity,ev.event_actionlist,ev.event_source,ev.event_info,ev.event_message,ev.dependency_main,ev.dependency_comment
  FROM events ev
  WHERE ev.event_severity='warning'
  UNION
  SELECT ev.serialid,ev.time_processed,ev.time_created,ev.sender_console,ev.sender_manager,ev.sender_map,ev.sender_device,ev.event_type,ev.event_command,ev.event_severity,ev.event_actionlist,ev.event_source,ev.event_info,ev.event_message,ev.dependency_main,ev.dependency_comment
  FROM  events ev
  JOIN dep_event dev ON ev.serialid = dev.dependency_main
             OR dev.serialid = ev.dependency_main
)
SELECT *
FROM dep_event

説明する 分析する

"CTE Scan on dep_event  (cost=203955680.32..204419627.58 rows=23197363 width=1034) (actual time=11.204..4602.977 rows=234159 loops=1)"
"  CTE dep_event"
"    ->  Recursive Union  (cost=0.00..203955680.32 rows=23197363 width=176) (actual time=11.200..4468.402 rows=234159 loops=1)"
"          ->  Seq Scan on events ev  (cost=0.00..47382.98 rows=227693 width=176) (actual time=11.181..2145.798 rows=225365 loops=1)"
"                Filter: ((event_severity)::text = 'warning'::text)"
"          ->  Nested Loop  (cost=4.89..20344435.01 rows=2296967 width=176) (actual time=1.593..610.347 rows=5863 loops=3)"
"                ->  WorkTable Scan on dep_event dev  (cost=0.00..45538.60 rows=2276930 width=16) (actual time=0.050..33.360 rows=78053 loops=3)"
"                ->  Bitmap Heap Scan on events ev  (cost=4.89..8.90 rows=1 width=176) (actual time=0.005..0.005 rows=0 loops=234159)"
"                      Recheck Cond: ((serialid = dev.dependency_main) OR (dev.serialid = dependency_main))"
"                      ->  BitmapOr  (cost=4.89..4.89 rows=1 width=0) (actual time=0.003..0.003 rows=0 loops=234159)"
"                            ->  Bitmap Index Scan on serialid  (cost=0.00..2.44 rows=1 width=0) (actual time=0.000..0.000 rows=0 loops=234159)"
"                                  Index Cond: (serialid = dev.dependency_main)"
"                            ->  Bitmap Index Scan on dep_main  (cost=0.00..2.45 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=234159)"
"                                  Index Cond: (dev.serialid = dependency_main)"
"Total runtime: 4621.138 ms"
4

1 に答える 1

0

一般に、これは再帰的な CTE (WITH RECURSIVEステートメント) の明確なケースです。

次のようになります。

WITH RECURSIVE dep_event AS (
  SELECT ev.serialid, ev.time, ev.sender, ev.dependency
  FROM events ev
  WHERE ev.sender = 'John' -- start condition here
  UNION
  SELECT ev.serialid, ev.time, ev.sender, ev.dependency
  FROM  events ev
  JOIN dep_event dev ON ev.serialid = dev.dependency -- connect conditions here
                     OR dev.serialid = ev.dependency
)
SELECT *
FROM dep_event;

追加情報はこちらhttp://www.postgresql.org/docs/current/static/queries-with.html

このRECURSIVEクエリは、あらゆるレベルの依存関係を処理します。

UPD: クエリのいくつかの誤りを修正し、SQLFiddle の例を作成しましたhttp://sqlfiddle.com/#!12/4e915/4

于 2012-11-22T10:30:06.037 に答える