SELECT .. FROM(SELECT .. FROM ..).如何改进此查询?

Awe*_*ebb 3 sql sqlite

我正在学习SQL并且已经阅读了GalaXQL应用程序的章节.

我已经写了下面的问题来回答"Hilight the star(或星星)"这个行星在星系中具有最高轨道距离.记得在开始前清除旧的hilights.

此查询返回结果starid:23334,当插入hilight表时,允许我前进.但是,在将结果交还给我之前,程序会挂起很长时间,因此我怀疑从数据库中提取这些信息的效率要高得多.

此查询有效,但需要很长时间才能处理,如何改进此查询?

INSERT INTO hilight 
SELECT DISTINCT s.starid 
FROM planets AS p, stars AS s, moons AS m 
WHERE s.starid=(SELECT starid 
                FROM planets 
                WHERE orbitdistance=(SELECT MAX(orbitdistance) 
                                     FROM planets));
Run Code Online (Sandbox Code Playgroud)

我在这个查询结构背后的逻辑

首先找到距离"行星"表有最大轨道距离的行星.

其次是将"最高轨道距离"的值与"行星"表的"轨道距离"字段进行比较,并返回与该字段相关的"星形".

第三步将"行星"表中的"starid"字段的值与表格"stars"中的字段"starid"进行比较,然后将"starid"插入表"hilight".

数据结构:

在此输入图像描述

Zan*_*ane 7

好吧,让我们从查看您的基本查询开始吧.我知道你已经有一个有效的答案,但我觉得我需要向你解释你的查询中发生了什么.

INSERT INTO hilight 
SELECT DISTINCT 
    s.starid 
FROM planets AS p, stars AS s, moons AS m 
WHERE s.starid=(
    SELECT 
        starid 
    FROM planets 
    WHERE orbitdistance=(
            SELECT 
                MAX(orbitdistance) 
            FROM planets
            )
        );
Run Code Online (Sandbox Code Playgroud)

所以在你的FROM子句中你也使用了几个旧式连接.你也错过了一个ON条款.这被称为CROSS JOIN,它将产生我们称之为笛卡儿积的产品.结果集将第一个表中的行数乘以第二个表中的行数,依此类推.

因此,我们可以通过简单地修复连接语法并加入您在图表中显示的关系来解决这个问题.

INSERT INTO hilight 
SELECT --DISTINCT probably no longer needed as we aren't artifficially creating duplicate rows
    s.starid 
FROM planets AS p
inner join stars AS s
    on s.StarID = p.starid 
inner join moons AS m 
    m.planetID = p.planetID
WHERE s.starid=(
    SELECT 
        starid 
    FROM planets 
    WHERE orbitdistance=(
            SELECT 
                MAX(orbitdistance) 
            FROM planets
            )
        );
Run Code Online (Sandbox Code Playgroud)

进一步分析后,您将加入表卫星,但不使用任何数据,也不限制结果集.这意味着您在查询中没有获得任何好处,并且可以直接删除.

INSERT INTO hilight 
SELECT --DISTINCT probably no longer needed as we aren't artifficially creating duplicate rows
    s.starid 
FROM planets AS p
inner join stars AS s
    on s.StarID = p.starid 
WHERE s.starid=(
    SELECT 
        starid 
    FROM planets 
    WHERE orbitdistance=(
            SELECT 
                MAX(orbitdistance) 
            FROM planets
            )
        );
Run Code Online (Sandbox Code Playgroud)

现在进一步分析,如果我们看一下你的WHERE条款,它似乎是多余的.在我可以简单地将最大轨道距离与行星表匹配时,我似乎没有理由两次去行星表获得你的谓词.这也消除了加入桌上明星的任何理由.

INSERT INTO hilight 
SELECT 
    p.starid 
FROM planets AS p
WHERE p.orbitdistance=
    (
    SELECT 
        MAX(orbitdistance) 
    FROM planets
    )
Run Code Online (Sandbox Code Playgroud)

由于我们没有生成如此多的重复行,因此生成的查询更加简单并且应该运行得更快.我希望能够对你的查询中发生的事情有所了解.

更新:经过进一步审查,这个GalaSQL看起来非常糟糕,并且大量过时的信息,我强烈建议不要使用它.