Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 我怎样才能使这个查询更好?_Sql_Sqlite_Group By_Having Clause - Fatal编程技术网

Sql 我怎样才能使这个查询更好?

Sql 我怎样才能使这个查询更好?,sql,sqlite,group-by,having-clause,Sql,Sqlite,Group By,Having Clause,我正在通过GALAXQL学习SQL 我正在学习第17课-分组 以下是场景: 让我们来看看我们尚未涉及的几个精选操作, 即分组和有 这些操作的语法如下所示: SELECT中的GROUP BY命令会导致生成多个输出行 合并成一行。这可能非常有用,例如, 我们希望以表格形式生成新的统计数据 例如,找出每颗恒星的最高强度 同学们,我们要做: HAVING操作符的工作方式与WHERE几乎相同,除了 分组完成后应用它。因此,我们可以 计算每个类别的亮度总和,并裁剪出类别 如果总和高于,比如说,150 照亮轨

我正在通过GALAXQL学习SQL

我正在学习第17课-分组

以下是场景:

让我们来看看我们尚未涉及的几个精选操作, 即分组和有

这些操作的语法如下所示:

SELECT中的GROUP BY命令会导致生成多个输出行 合并成一行。这可能非常有用,例如, 我们希望以表格形式生成新的统计数据

例如,找出每颗恒星的最高强度 同学们,我们要做:

HAVING操作符的工作方式与WHERE几乎相同,除了 分组完成后应用它。因此,我们可以 计算每个类别的亮度总和,并裁剪出类别 如果总和高于,比如说,150

照亮轨道最多的恒星(行星和卫星的组合)。 (请注意,验证查询有些繁重,因此请耐心等待。) 按“好的,我完成了…”。


这是我的答案

SELECT stars.starid AS HighStar, 
(COUNT(planets.planetid) + COUNT(moons.moonid)) AS OrbitalsTotal 
FROM stars
LEFT OUTER JOIN planets
ON stars.starid = planets.starid
LEFT OUTER JOIN moons
ON planets.planetid = moons.planetid
GROUP BY stars.starid
ORDER BY OrbitalsTotal DESC;
这个查询向我显示,拥有最多oribtals的恒星有170个轨道

那么:

INSERT INTO hilight SELECT result.HighStar
FROM result
INNER JOIN stars
ON result.HighStar = stars.starid
WHERE result.OrbitalsTotal = 170

我想问你的问题是,我怎样才能使这个问题变得更好?我不想对170个轨道进行硬编码,也不想创建第二个查询来插入数据。

如果您用
选择TOP(1)…
开始第一个查询,那么这只会给出第一个结果。
TOP()
语法可以与给出那么多行的硬数字或给出总数百分比的百分比一起使用。

只需使用第一个查询,并添加子句
LIMIT 1
,以仅返回第一条记录:

SELECT stars.starid AS HighStar, 
       (COUNT(planets.planetid) + COUNT(moons.moonid)) AS OrbitalsTotal 
FROM stars
     LEFT OUTER JOIN
     planets ON stars.starid = planets.starid
     LEFT OUTER JOIN
     moons ON planets.planetid = moons.planetid
GROUP BY stars.starid
HAVING OrbitalsTotal = (SELECT MAX(Orbitals)
                        FROM (SELECT (COUNT(planets.planetid) + COUNT(moons.moonid)) Orbitals
                              FROM stars
                                   LEFT OUTER JOIN
                                   planets ON stars.starid = planets.starid
                                   LEFT OUTER JOIN
                                   moons ON planets.planetid = moons.planetid
                              GROUP BY stars.starid))
INSERT INTO hilight
SELECT stars.starid AS HighStar
FROM stars
LEFT OUTER JOIN planets
ON stars.starid = planets.starid
LEFT OUTER JOIN moons
ON planets.planetid = moons.planetid
GROUP BY stars.starid
ORDER BY COUNT(planets.planetid) + COUNT(moons.moonid) DESC
LIMIT 1

到了GalaXQL的第17章,我们还没有学会极限,我想我们可以不用所有的左外连接(借用Dale M的(在“轨道”之前缺少“AS”,尽管它仍然有效?!))来更接近我们在该节最后一个例子中看到的

那么:

DELETE FROM hilight;
INSERT INTO hilight 
SELECT HighStar FROM (
    SELECT stars.starid AS HighStar, 
        (COUNT(planets.planetid) + COUNT(moons.moonid)) AS OrbitalsTotal 
    FROM stars, planets, moons 
    WHERE stars.starid = planets.starid
        AND planets.planetid = moons.planetid
    GROUP BY stars.starid
    HAVING OrbitalsTotal = (
        SELECT MAX(Orbitals) FROM (
            SELECT (COUNT(planets.planetid) + COUNT(moons.moonid)) AS Orbitals
            FROM stars, planets, moons
            WHERE stars.starid = planets.starid
                AND planets.planetid = moons.planetid
            GROUP BY stars.starid))
);
SELECT * FROM hilight;
使用LIMIT,我们还可以避免左侧外部联接,而不必重复我们的选择:

DELETE FROM hilight;
INSERT INTO hilight
SELECT bodygroup FROM (
    SELECT stars.starid as bodygroup, 
        (COUNT(planets.planetid)+COUNT(moons.moonid)) AS bodycount
    FROM stars, planets, moons 
    WHERE stars.starid=planets.starid 
        AND planets.planetid=moons.planetid 
    GROUP BY stars.starid
    ORDER BY bodycount DESC) 
LIMIT 1;
SELECT * FROM hilight;
或者使用CREATE视图来避免在不使用LIMIT的情况下加倍努力,我们可以:

DELETE FROM hilight;    
CREATE VIEW bodyview AS
    SELECT stars.starid as bodygroup,
        (COUNT(planets.planetid)+COUNT(moons.moonid)) AS bodycount
    FROM stars, planets, moons
    WHERE stars.starid=planets.starid
       AND planets.planetid=moons.planetid
    GROUP BY stars.starid
    ORDER BY bodycount DESC;
INSERT INTO hilight SELECT bodygroup FROM bodyview  
    WHERE bodycount = (SELECT MAX(bodycount) FROM bodyview );
DROP VIEW bodyview;
SELECT * FROM hilight;

22336星没有170个轨道

它有97个轨道

检查卫星的数量

SELECT COUNT(moons.moonid) as moon_count
FROM stars JOIN planets
ON stars.starid=planets.starid
JOIN moons
ON planets.planetid=moons.planetid
WHERE stars.starid=22336
这是79颗卫星

现在检查行星的数量

SELECT COUNT(planets.planetid) AS planet_count
FROM stars JOIN planets
ON stars.starid=planets.starid
WHERE stars.starid=22336
这就产生了18颗行星

下面的SQL正确计算轨道计数并完成任务

INSERT INTO hilight
SELECT pc.starid FROM

(SELECT p.starid, COUNT(p.planetid) AS p_count
FROM planets AS p
GROUP BY p.starid) AS pc

JOIN

(SELECT p.starid, COUNT(m.moonid) AS m_count
FROM planets AS p JOIN moons AS m
ON p.planetid=m.planetid
GROUP BY p.starid) AS mc

ON pc.starid=mc.starid

ORDER BY p_count+m_count DESC
LIMIT 1

我在SQLLite中尝试了top,但出现了一个错误,即没有top函数。但是,想象一下这是可行的,hilights表中只有一列,而im在第一个查询中选择了两列。那么如何将starid放入hilights表中呢?与其添加另一个答案,不如更新/编辑这个答案。奇怪的是,回答这个问题的最佳方法不是使用having子句。SQLite是否支持派生表,即别名为的子查询?@DanBracuk Yes,
SELECT。。。FROM(SELECT…)AS alias…
受支持。感谢您的回复,我必须上床睡觉,现在正在工作,所以稍后将检查em。此解决方案错误地计算行星数。简而言之(planets.planetid)计算类似(卫星数量+没有卫星的行星数量)。有关正确的解决方案,请参阅。此解决方案正确计算了轨道数。这些解决方案还错误地计算了2n_卫星+n_行星(无_卫星)的轨道数。有关正确的解决方案,请参见此处:
DELETE FROM hilight;    
CREATE VIEW bodyview AS
    SELECT stars.starid as bodygroup,
        (COUNT(planets.planetid)+COUNT(moons.moonid)) AS bodycount
    FROM stars, planets, moons
    WHERE stars.starid=planets.starid
       AND planets.planetid=moons.planetid
    GROUP BY stars.starid
    ORDER BY bodycount DESC;
INSERT INTO hilight SELECT bodygroup FROM bodyview  
    WHERE bodycount = (SELECT MAX(bodycount) FROM bodyview );
DROP VIEW bodyview;
SELECT * FROM hilight;
SELECT COUNT(moons.moonid) as moon_count
FROM stars JOIN planets
ON stars.starid=planets.starid
JOIN moons
ON planets.planetid=moons.planetid
WHERE stars.starid=22336
SELECT COUNT(planets.planetid) AS planet_count
FROM stars JOIN planets
ON stars.starid=planets.starid
WHERE stars.starid=22336
INSERT INTO hilight
SELECT pc.starid FROM

(SELECT p.starid, COUNT(p.planetid) AS p_count
FROM planets AS p
GROUP BY p.starid) AS pc

JOIN

(SELECT p.starid, COUNT(m.moonid) AS m_count
FROM planets AS p JOIN moons AS m
ON p.planetid=m.planetid
GROUP BY p.starid) AS mc

ON pc.starid=mc.starid

ORDER BY p_count+m_count DESC
LIMIT 1