PostgreSQL存在的地方

2024-09-29 21:26:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我在思考如何正确地使用EXISTS(以及是否有一种正确的方法来使用EXISTS,或者我误解了它)。在

我正在反对Rigor模式(在这里为SQLAlchemy定义:https://github.com/blindsightcorp/rigor/blob/master/lib/types.py)。在

简而言之,我关心三个表:“percept”、“annotation”和“annotation_property”。注解属性有注解标识,注解有感知标识

我想找到所有具有具有特定注解属性(FOO=BAR)的注释的感知。在

Percepts可能有许多具有特定属性的注释,因此似乎EXISTS应该使事情变得更快。在

(相对较慢)选项是:

 SELECT DISTINCT(percept.*) FROM percept, annotation, annotation_property 
        WHERE percept.id = annotation.percept_id AND 
              annotation_property.annotation_id = annotation.id AND 
              annotation_property.name = 'FOO' AND annotation_property.value = 'BAR';

我将如何使用EXISTS来优化这一点?在

感觉第一步是这样的:

^{pr2}$

但我不知道该怎么办。。。。在


Tags: and方法id属性定义foosqlalchemyexists
2条回答

原始查询的问题(除了隐式连接语法外),是因为您将连接中的许多行合并在一起。然后进行聚合以删除重复项。在

只需从一个表中选择,就可以消除重复删除:

SELECT p.*
FROM percept p
WHERE EXISTS (SELECT 1
              FROM annotation a JOIN
                   annotation_property ap
                   ON ap.annotation_id = a.id AND 
                      ap.name = 'FOO' AND ap.value =  'BAR'
              WHERE p.id = a.percept_id 
             ) ;

这假设percept中的行没有重复项,但这似乎是一个合理的假设。在

首先,使用ANSI联接语法来区分联接条件和过滤条件。结果更易于阅读,并且可以更好地显示数据的结构:

SELECT DISTINCT(percept.*)
FROM
  percept
  JOIN annotation ON percept.id = annotation.percept_id
  JOIN annotation_property ON annotation_property.annotation_id = annotation.id
WHERE
    annotation_property.name = 'FOO'
    AND annotation_property.value = 'BAR'
;

如您所说,对主键列使用distinct,而不是一次对整个percept行使用distinct,但这仍然可能涉及到计算一个大的结果集,然后将其合并。它是exists()条件的替代品,而不是对条件的补充。在

WHERE子句中使用EXISTS条件可能如下所示:

^{pr2}$

相关问题 更多 >

    热门问题