我在这里已经阅读了很多答案,但这是我的第一个问题。我是新手,所以关于问题风格/格式的建议值得赞赏。
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个相关事件:2nd,3rd
(1)第一个目标 我想确保如果我发出一个WHERE语句ex: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|
我还需要Sue的事件(serialid == 2),因为它与John“主事件”有关
好结果:
| 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的依赖,但它不在thre结果中。好结果将是:
| 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 events WHERE“my conditions”
UNION ?? 魔法依赖收集器查询: - )
(注) 依赖性只能是一个层次。
提前谢谢你, 戴夫
更新
感谢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
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 :(得分: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