手头的任务是选择音乐家(pid)和每个演奏的乐器数量,包括仅在音乐会上演奏的乐器 - 这些乐器可能不在[play]表中。
我已经解决了它,但我读到如果可能的话,应该避免使用from子句中的子查询。出于好奇,有人能告诉我一个更有效的方法吗?或者这是一个很好的解决方案?我正在使用psql。
select a.pid, sum(a.instr)
from
(
select pid, count(instr) as instr from plays group by pid
union all
select pid, count(instr) as instr from concert group by pid
) as a
group by a.pid;
答案 0 :(得分:1)
此类查询不是问题。数据库的查询优化器将负责充分利用此查询。在某些情况下,INNER JOIN
将转换为与子SELECT
完全相同的执行计划。
如果您认为查询有问题,您可以随时启动psql的EXPLAIN ANALYZE
功能。这将为您提供查询实际执行的操作的概述。这样,您还可以比较编写查询的不同方法。
你给出的例子......我认为你不能在没有子查询的情况下解决这个问题。我认为你选择的方式很好。涉及某些LEFT JOIN
的任何内容都将更难以阅读。
答案 1 :(得分:0)
<强>优点强>
<强>缺点强>
使用子查询时,查询优化器可能需要执行其他步骤,因此执行时间比连接要长。
对于父查询的每一行,执行一次不相关的子查询。如果这种子查询处理大量数据,您应该会花费很长时间来处理数据。
可能的解决方案:
您可以创建用于存储子查询数据的临时表,然后使用JOIN完成查询。请记住,使用JOIN比使用子查询更好。 How to Create a Table
使用with子句。 WITH
提供了一种编写辅助语句以便在更大的查询中使用的方法。这些语句(通常称为公用表表达式或CTE)可以被视为定义仅针对一个查询存在的临时表。它允许您只执行一次子查询,而不是为每一行执行子查询。 How to Use With Clause
注意:您应该避免使用UNION或UNION ALL。