两个SQL表中的任何一个都有一个值

时间:2017-06-10 22:52:32

标签: sql postgresql postgresql-9.6

我有两个表,task_list_shareetask_list_assignee。它们都引用了task_list表。

还有一个task表,其中包含对task_list表的引用,因为task中始终存在task_list

鉴于task,我想知道task_list_shareetask_list_assignee是否有值。现在我将它作为两个SQL语句来执行,如下所示:

SELECT count(*)
FROM task_list_assignee a 
INNER JOIN task_list l ON l.uid = a.task_list_uid
INNER JOIN task t ON t.task_list_uid = l.uid
WHERE t.uid = ?

SELECT count(*)
FROM task_list_sharee s 
INNER JOIN task_list l ON l.uid = s.task_list_uid
INNER JOIN task t ON t.task_list_uid = l.uid
WHERE t.uid = ?

如果其中任何一个非零,那我就是平底船。我认为这必须只是一个SQL语句,但我有点难过。

2 个答案:

答案 0 :(得分:1)

多个连接的完整计数性能(LEFT JOIN更多)可能会很快恶化。虽然您只需要证明存在单行,但不需要这样做。使用EXISTS - 名称为true - 以允许最佳查询计划:

SELECT EXISTS (
   SELECT 1
   FROM   task t
   WHERE  t.uid = ?  -- provide uid here
   AND   (
      EXISTS (
         SELECT 1
         FROM   task_list_assignee
         WHERE  task_list_uid = t.task_list_uid
         )
   OR EXISTS (
         SELECT 1
         FROM   task_list_sharee
         WHERE  task_list_uid = t.task_list_uid
         )
      )
   );

应比完整计数更快。

我也切断了中间人。加入task_list只会确定task_list中的相关行存在 - 这样会浪费时间:

  

task中始终存在task_list

理想情况下使用FK约束实现强制参照完整性。 如果没有实际的表格定义,我必须做出有根据的猜测。

要为任何表格大小设置 fast ,您需要3个btree(默认)索引

task(uid, task_list_uid)
task_list_assignee(task_list_uid)
task_list_sharee(task_list_uid)

答案 1 :(得分:0)

如果以Task作为基表开始并执行一系列左连接,您应该能够使用coalesce确定哪些任务具有受理人和sharee的值:

select count(*)
from task as t
    left join
    task_list as l
    on t.task_list_uid = l.uid
    left join
    task_list_assignee as a
    on l.uid = a.task_list_uid
    left join
    task_list_sharee as s
    on l.uid = s.task_list_uid
where coalesce( a.task_list_uid, s.task_list_uid ) is not null
      and t.uid = ?

SQL小提琴here