我正在通过GALAXQL http://sol.gfxile.net/galaxql.html
学习SQL我在第17课 - GROUP BY / HAVING
以下是该方案:
让我们看看我们尚未涉及的几个SELECT操作, 即GROUP BY和HAVING。
这些操作的语法如下所示:
SELECT columns FROM table GROUP BY column HAVING expression
SELECT中的GROUP BY命令会导致多个输出行 合并成一排。例如,如果这个非常有用 我们希望以表格的形式生成新的统计数据。
例如,从星星中找出最高强度 上课,我们会这样做:
Select Class, Max(Intensity) As Brightness From Stars Group By Class Order By Brightness Desc
HAVING操作符与WHERE的工作方式几乎相同,除外 在分组完成后应用它。因此,我们可以 计算每个类的亮度之和,并裁剪出类 其中总和高于150。
SELECT class, SUM(intensity) AS brightness FROM stars GROUP BY class HAVING brightness < 150 ORDER BY brightness DESC
我们可以引用未在HAVING子句中选择的列, 但结果可能难以理解。你应该可以 使用HAVING子句中的聚合函数(例如, 亮度&lt; MAX(亮度)* 0.5,但这似乎会使电流崩溃 SQLite的版本。
与联接结合使用时,GROUP BY变得非常方便。要找出答案 每颗恒星的行星数量,我们可以做到:
SELECT stars.starid AS starid, COUNT(planets.planetid) AS planet_count FROM planets, stars WHERE stars.starid=planets.starid GROUP BY stars.starid
Hilight是大多数轨道的恒星(行星和卫星的组合)。 (请注意,验证查询有点重,所以请耐心等待 按“好的,我已经完成......”)。
这是我的回答
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轨道,我不想创建第二个查询来插入数据。
答案 0 :(得分: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))
答案 1 :(得分:1)
只需使用您的第一个查询,并添加条款LIMIT 1
以仅返回第一条记录:
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
答案 2 :(得分:1)
Star 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
答案 3 :(得分:0)
如果您使用SELECT TOP(1) ...
开始第一个查询,那么这将只为您提供第一个结果。 TOP()
语法可以与硬编号一起使用,该编号可以提供许多行或百分比,从而提供总数的百分比。
答案 4 :(得分:0)
通过GalaXQL的第17章,我们还没有学到LIMIT,而且我认为我们可以在没有所有LEFT OUTER JOINS的情况下做到这一点(借用Dale M&#39;其中缺少&#34; AS&# 34;之前&#34; Orbitals&#34;虽然它仍然有效?!))与我们在该部分的最后一个例子中看到的更接近。
那怎么样:
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,我们也可以避免LEFT OUTER JOIN而不必复制我们的选择:
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 VIEW试图避免在不使用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;