sql - 优化sql查询: check for all rows in table B if any rows in table C reference the same row in table A

标签 sql postgresql query-optimization

我有 3 个表,A、B 和 C 的结构如下

CREATE TABLE a (
    id SERIAL NOT NULL PRIMARY KEY
);

CREATE TABLE b (
    id SERIAL NOT NULL PRIMARY KEY,
    a_id INT REFERENCES a(id) ON DELETE CASCADE
);

CREATE TABLE c (
    id SERIAL NOT NULL PRIMARY KEY,
    a_id INT REFERENCES a(id) ON DELETE CASCADE
);

关系是多对一的。我想要的是,对于表 b 中的每一行,我想检查表 c 中的任何行是否引用表 a 中的同一行。现在,我已经有了查询

SELECT
    b.id,
    true
FROM
    b
WHERE EXISTS (
    SELECT 1
    FROM c
    WHERE b.a_id = c.a_id
)
UNION
SELECT
    b.id,
    false
FROM
    b
WHERE NOT EXISTS (
    SELECT 1
    FROM c
    WHERE b.a_id = c.a_id
)
ORDER BY id

虽然我不确定,但我认为这是在做双重工作,并遍历表格两次,我想知道如何优化它以仅遍历表格一次。

是否可以使用简单的查询,还是我必须做任何复杂的事情?

最佳答案

只需将 EXISTS 子句移至 SELECT 子句即可。

SELECT
  b.id,
  EXISTS (SELECT null FROM c WHERE c.a_id = b.a_id) AS c_exists
FROM b;

IN 子句相同,我更喜欢它更简单一点:

SELECT
  id,
  a_id IN (SELECT c.a_id FROM c) AS c_exists
FROM b;

关于sql - 优化sql查询: check for all rows in table B if any rows in table C reference the same row in table A,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73135653/

相关文章:

postgresql - 在 jOOQ 更新中使用 jsonb_set

PHP/MySql - 查询具有嵌套对象的对象的最佳方式

sql - 使用 BigQuery 取消嵌套 customDimensions

Mysql 使用 Perl DBI 跨两个表删除重复行

mysql - 如何获取具有 ROUND 值的 DateTime?

sql - 为什么我的表从 pg_catalog.pg_class 中消失了? (或者,如何找到主键列?)

sql-server - 数据库引擎在 SQL 级别的兼容性如何?

ruby-on-rails - rails 4 : changing database to postgresql (from sqlite3)

php - MYSQL : SET value in an UPDATE query when all conditions of subquery are satisfied

sql - 如果oracle数据库中的某个表是空表统计的,那么如何恢复该表的原始统计信息呢?