Postgresql链接查询相同表

Postgresql链接查询相同表,postgresql,hyperlink,Postgresql,Hyperlink,我在这里读了很多答案,但这是我的第一个问题。我是一个新手,所以对于问题风格/格式的建议非常感谢 PostgreSQL 9.1 我有一张叫做事件的桌子。primarykey=serialid ============================================== |serialid| time|sender|dependency| | 1| 2012-11-22 14:40| John| | |

我在这里读了很多答案,但这是我的第一个问题。我是一个新手,所以对于问题风格/格式的建议非常感谢

PostgreSQL 9.1 我有一张叫做事件的桌子。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语句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“main event”

好结果:

   |       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) 第二个目标:让我们看看“良好结果”表:

有些事件没有“主要事件”。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语句结果的所有依赖项

大概是这样的:

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;
从“我的条件”所在的事件中选择*

联盟?? 魔法依赖项收集器查询:-)

(注) 依赖关系只能有一级深度

提前谢谢大家,, 戴夫

更新

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

一般来说,这是递归CTE(
带有递归
语句)的明显情况

它看起来是这样的:

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;
这里有更多信息

递归
查询将处理任何级别的依赖项


UPD:修复了查询中的一些错误并创建了SQLFIDLE示例

谢谢你,这正是我所需要的。不幸的是,查询运行得非常慢。你有什么办法加快速度吗?删除递归?@David Molnar你能提供查询的
解释分析
吗?我的示例简化了,实际数据库有更多的列和不同的名称。我创建了一个依赖项索引,查询速度大大加快。现在很好。当然,我可以为您提供查询计划。我的答案已经完全回答了,不管怎样,您需要查询计划吗?我需要
解释分析
来帮助您提高查询性能。如果您对当前查询性能感到满意-我不再需要
解释分析
。我很满意。为了好玩和学习,我附上了解释分析