【问题标题】:SQL : transform union query to a single querySQL:将联合查询转换为单个查询
【发布时间】:2016-11-24 18:23:14
【问题描述】:

我有一个这样的数据库架构

用户
身份证
矩阵

文档
身份证
标题
user_id(用户的外键)
模式(可以接受 PUBLIC 或 PRIVATE)

我想检索所有公开的文档以及属于给定用户(矩阵)的所有文档

我做了一个这样的联合查询:

select * document d
Inner join user u ON u.id = d.user_id 
and u.matricule ='matricule1'
UNION
select * from document d
Inner join user u ON u.id = d.user_id 
where d.mode ='PUBLIC' 

效果很好,但我可以用另一种方式(我在某处读到联合查询不利于性能)获得相同的结果吗?例如子查询?

非常感谢

【问题讨论】:

  • @a_horse_with_no_name 。我正在使用 postgreSQL 。

标签: sql postgresql


【解决方案1】:
select distinct *
from document d
Inner join user u ON u.id = d.user_id 
where u.matricule = 'matricule1' or d.mode ='PUBLIC' 

SELECT DISTINCT 删除重复项,就像 UNION 一样。 (也许你只想要SELECT?)

【讨论】:

  • 这么快。非常感谢:)
  • 如果他在两个表中都有主键(大多数表应该)那么DISTINCT 真的有必要吗,因为他要回来*?这只是吹毛求疵和猜测,我想把这个想法扔出去,反正我 +1 了。
  • @RaduGheorghiu,可能不需要,但 OP 没有指定 pk。
【解决方案2】:

假设您只想要document 表中的列,这也可以写成:

select * 
from document d
where exists (select * 
              from "user" u
              where u.id = d.user_id
                and u.matricule = 'matricule1')
or d.mode ='PUBLIC' 

这使得删除重复项变得不必要,UNION 隐式执行并且对于JOIN 解决方案来说是必要的。

但您必须检查两种解决方案的执行计划。在某些情况下,UNION 解决方案可能确实比上述(或JOIN)更快。这在很大程度上取决于所使用的 DBMS(例如,对于 Postgres 或 Oracle,在这种情况下我不认为会有很大的不同)

【讨论】:

  • 。非常感谢,另一个很棒的解决方案。 +1 :) 。如何检查查询的执行计划?请问有好的链接吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 2015-10-10
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 2017-04-25
相关资源
最近更新 更多