在这种情况下,如何避免嵌套SQL查询?

在这种情况下,如何避免嵌套SQL查询?,sql,mysql,nested-query,Sql,Mysql,Nested Query,我有一个SQL问题,与和问题相关,但不同。基本上,我想知道如何避免嵌套查询 比方说,我有一个巨大的工作表,在他们的历史上由一家公司执行。这些作业以年、月、位置和属于作业所用工具的代码为特征。此外,我还有一个工具表,将工具代码转换为工具描述和关于工具的更多数据。现在他们想要一个网站,在那里他们可以使用下拉框选择年、月、地点和工具,然后显示匹配的工作。我想在最后一个下拉列表中只填充与年、月和位置的before选择相匹配的相关工具,因此我编写了以下嵌套查询: SELECT c.tool_code, t

我有一个SQL问题,与和问题相关,但不同。基本上,我想知道如何避免嵌套查询

比方说,我有一个巨大的工作表,在他们的历史上由一家公司执行。这些作业以年、月、位置和属于作业所用工具的代码为特征。此外,我还有一个工具表,将工具代码转换为工具描述和关于工具的更多数据。现在他们想要一个网站,在那里他们可以使用下拉框选择年、月、地点和工具,然后显示匹配的工作。我想在最后一个下拉列表中只填充与年、月和位置的before选择相匹配的相关工具,因此我编写了以下嵌套查询:

SELECT c.tool_code, t.tool_description
FROM (
 SELECT DISTINCT j.tool_code
 FROM jobs AS j
 WHERE j.year = ....
        AND j.month = ....
 AND j.location = ....
) AS c
LEFT JOIN tools as t
ON c.tool_code = t.tool_code
ORDER BY c.tool_code ASC

我求助于这个嵌套查询,因为它比在整个数据库上执行连接并从中进行选择要快得多。这大大缩短了我的查询时间。但正如我最近读到的,我想知道我的这种方法是否错了。我应该以不同的方式重写我的查询吗?怎么做呢?

不,你不应该,你的问题很好

只需创建一个关于年、月、地点、工具代码和工具代码的索引,就可以使用GROUP-BY的索引

您提供的文章描述了SELECT…(选择…)中的子查询谓词,而不是嵌套查询SELECT FROM SELECT

即使是子查询,本文也是错误的:虽然MySQL不能优化所有子查询,但它可以很好地处理SELECT…谓词

我不知道作者为什么选择在这里写:

为什么他们认为这将有助于提高性能,但鉴于widgetID已被索引,MySQL将只转换此查询:

SELECT  id, name, price
FROM    widgets
WHERE   id IN
        (
        SELECT  widgetId
        FROM    widgetOrders
        )
SELECT  DISTINCT w.id,w.name,w.price
FROM    widgets w
INNER JOIN
        widgetOrders o
ON      w.id = o.widgetId
进入索引_子查询

本质上,这与EXISTS子句类似:每个窗口小部件行将执行一次内部子查询,并添加额外的谓词:

SELECT  NULL
FROM    widgetOrders
WHERE   widgetId = widgets.id
在widgetOrders的第一场比赛中停下来

此查询:

SELECT  id, name, price
FROM    widgets
WHERE   id IN
        (
        SELECT  widgetId
        FROM    widgetOrders
        )
SELECT  DISTINCT w.id,w.name,w.price
FROM    widgets w
INNER JOIN
        widgetOrders o
ON      w.id = o.widgetId

将不得不使用“临时”来消除重复项,并且速度会慢得多。

不,您不应该这样做,您的查询很好

只需创建一个关于年、月、地点、工具代码和工具代码的索引,就可以使用GROUP-BY的索引

您提供的文章描述了SELECT…(选择…)中的子查询谓词,而不是嵌套查询SELECT FROM SELECT

即使是子查询,本文也是错误的:虽然MySQL不能优化所有子查询,但它可以很好地处理SELECT…谓词

我不知道作者为什么选择在这里写:

为什么他们认为这将有助于提高性能,但鉴于widgetID已被索引,MySQL将只转换此查询:

SELECT  id, name, price
FROM    widgets
WHERE   id IN
        (
        SELECT  widgetId
        FROM    widgetOrders
        )
SELECT  DISTINCT w.id,w.name,w.price
FROM    widgets w
INNER JOIN
        widgetOrders o
ON      w.id = o.widgetId
进入索引_子查询

本质上,这与EXISTS子句类似:每个窗口小部件行将执行一次内部子查询,并添加额外的谓词:

SELECT  NULL
FROM    widgetOrders
WHERE   widgetId = widgets.id
在widgetOrders的第一场比赛中停下来

此查询:

SELECT  id, name, price
FROM    widgets
WHERE   id IN
        (
        SELECT  widgetId
        FROM    widgetOrders
        )
SELECT  DISTINCT w.id,w.name,w.price
FROM    widgets w
INNER JOIN
        widgetOrders o
ON      w.id = o.widgetId

必须使用“临时”来消除重复项,而且速度会慢得多。

您可以通过使用“分组依据”来避免子查询,但如果子查询的性能更好,请保留它


为什么要使用左联接而不是联接到联接工具?

可以通过使用GROUP by来避免子查询,但如果子查询性能更好,请保留它


为什么使用左联接而不是联接到联接工具?

因为我还没有在表之间设置外键关系。在我这样做之后,我可以切换到一个连接,但目前仍然可以将未知工具代码的作业添加到数据库中。我需要这些作业仍然在select中弹出,因为我还没有在表之间设置外键关系。在我这样做之后,我可以切换到一个连接,但目前仍然可以将未知工具代码的作业添加到数据库中。我需要这些作业仍然在选择窗口中弹出。