2012-11-22 44 views
2

我已經閱讀了很多答案,但這是我的第一個問題。我是新手,所以關於問題風格/格式的建議值得讚賞。Postgresql鏈接查詢相同的表

PostgreSQL 9.1 我有一個名爲events的表。的PrimaryKey = serialid

============================================== 
    |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個依賴的事件:第2,第3

(1)第一個進球 我想確保,如果我做一個WHERE語句例如:WHERE發送=「約翰」每一個相關的事件也存在於結果表

壞的結果:

|  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| 

我還需要蘇的事件(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)第二個目標:讓我們看看「好成績」表:

|  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語句的結果,所有的家屬我可以指定自定義。

是這樣的:

SELECT * FROM比賽時, 「我的條件」

UNION? 魔法依賴收集器查詢:-)

(NOTE) 依賴關係可能只有一個深度。

謝謝你在前進, 戴夫

UPDATE

感謝伊戈爾我得到了我真正的查詢中我真正的數據庫:

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 

EXPLAIN ANALYZE

"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" 

回答

0

一般al - 這是一個明確的遞歸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

+0

謝謝伊戈爾這正是我需要的。 不幸的是,查詢運行速度非常緩慢。你有什麼想法加快它,索引?刪除遞歸? –

+0

@David Molnar你能否提供查詢的'EXPLAIN ANALYZE'? –

+0

我的例子是簡化了真正的數據庫有更多的列和不同的名稱。我創建了一個依賴關係的索引,查詢變得更快。現在很好。當然,我可以爲您提供查詢計劃。我的答案已完全解答,無論如何你需要查詢計劃嗎? –