无需复制整个查询即可获得union的结果

时间:2017-03-14 20:27:12

标签: sql postgresql

我需要列出2016年和2017年的所有月份,为此我使用了旧的UNION ALL

select *
from year2016
  join months on months.year_id = year2016.id

union all

select *
from year2017
  join months on months.year_id = year2017.id

它按预期工作但如果我加入另一个表,我必须在两个查询中复制

有更好的方法吗? 类似的东西:

select *
from year2016, year2017
  join months on months.year_id in(year2016.id, year2017.id)

我的数据库是postgresql 9.4但我相信它至少对其他数据库也很有用。

[编辑]

正如Gordon Linoff指出的那样,我只是从几个月开始选择,但这不是主意,所以现在选择一切

3 个答案:

答案 0 :(得分:0)

您可以随时执行以下操作:

select m.*
from months m
where exists (select 1 from year2016 y where y.id = m.year_id) or
      exists (select 1 from year2017 y where y.id = m.year_id);

如果您只是从months表格中进行选择,则除了union之外还有其他方法。

答案 1 :(得分:0)

Postgres支持公用表表达式,

  • 将您的初始联盟包含在CTE条款
  • 在CTE后面的查询中引用连接一侧的CTE名称。

它们是一种很好的方式来表达您的查询,以便清楚每个查询层完成的内容,您甚至可以自己运行CTE并慢慢添加额外的CTE以测试中间步骤。在我看来,这比嵌套查询在可读性,可测试性方面要好得多,并且更容易让未来的开发人员围绕它们进行包装。它还允许您评论每个CTE,以便将来的开发人员更容易掌握每个步骤的作用。性能损失应该可以忽略不计(在其他DBMS中),但我不是Postgre的专家,不能肯定地说。

https://www.postgresql.org/docs/current/static/queries-with.html

答案 2 :(得分:0)

我不确定你在表year2016, year2017中有什么。我的猜测是那些常数。

所以你可以做类似

的事情
SELECT months.*
FROM months
WHERE month.year_id IN (2016,2017)