在 SQL 查询中使用 JOIN 而不是子查询

问题描述 投票:0回答:1

我有一个 SQL 查询,可以运行,但速度很慢。我想知道是否有更有效的方法来使用连接来表达它。

场景

表:

productions
scripts
和连接表、
productions_scripts

制作
id(整数)
制作(文字)
脚本
id(整数)
脚本(文本)
规范(布尔)
制作脚本
id(整数)
生产_id(整数)
script_id(整数)

要求

返回所有作品及其相关脚本的列表,其中作品具有多个“规范”类型的脚本。

当前查询:

SELECT productions.id AS production_id, productions.production,
       scripts.id AS script_id, scripts.script
FROM scripts, productions, productions_scripts
WHERE productions.id IN (SELECT productions_scripts.production_id
                         FROM productions_scripts, scripts
                         WHERE scripts.id = productions_scripts.script_id
                           AND scripts.canonical = 1
                         GROUP BY production_id
                         HAVING COUNT(production_id) > 1
                         )
AND productions.id = productions_scripts.production_id
AND scripts.id = productions_scripts.script_id
ORDER BY production_id;

问题: 查询有效,但需要很长时间才能运行。

我在编写查询时遇到的主要困难是获取具有多个规范脚本的产生式的计数,同时要求为每个匹配的产生式脚本组合输出一行,而不仅仅是

production_id
的唯一值。

看来我得用

GROUP BY production_id
来计数了。但这也会导致
production_id
输出唯一值。因此就有了子查询。

sql mysql join subquery query-optimization
1个回答
0
投票

您可以使用窗口函数代替子查询。

SELECT
  p.production_id,
  p.production,
  s.script_id,
  s.script
FROM (
    SELECT
      p.id AS production_id,
      p.production,
      s.id AS script_id,
      s.script,
      COUNT(CASE WHEN s.canonical = 1 THEN 1 END)
         OVER (PARTITION BY p.production_id) AS countCanonical
    FROM scripts s
    JOIN productions_scripts ps
      ON s.id = ps.script_id
    JOIN productions p
      ON p.id = ps.production_id
) p
WHERE p.canonicalCount > 1
ORDER BY production_id;

请注意,您应该使用显式连接语法,而不是逗号=连接。

© www.soinside.com 2019 - 2024. All rights reserved.