我有一个按城市,侧栏分组的表格,用于输入唯一条目,我需要查询每个城市,边路组的最新条目。 (较新的条目始终具有较高的时间戳值)
在SQLite中,我可以使用GROUP BY来完成这项工作:http://sqlfiddle.com/#!5/6c1c4/1/0
但在MySQL中,它不能以这种方式工作:http://sqlfiddle.com/#!9/9ead9/1/0
我认为我在这里滥用/滥用GROUP BY,但我怎么能有MySQL和SQLite的正确陈述?
答案 0 :(得分:2)
在您的示例中,MySQL和SQLite都违反了SQL标准。
在标准SQL中(由所有主要SQL引擎支持),如果在GROUP BY
语句中使用SELECT
,则SELECT
列表中允许的唯一表达式是GROUP BY
中列出的列1}},或聚合函数调用(如count()
,sum()
,avg()
等),超过任何其他列。
大多数SQL引擎:PostgreSQL,Oracle,MSSQL,DB2严格遵循此规则 - 它们不允许任何其他语法。
然而,MySQL和SQLite都决定在这方面更加宽松,我认为这是一个很大的错误和无休止的混淆源。虽然它似乎有效,但绝对不清楚究竟发生了什么。例如,查询生成的SQLite时间戳列看起来不像原始表源中存在的任何内容。如果您不想发生任何意外,请遵循标准。在您的情况下,它意味着使用如下语句:
SELECT
min(period),
side,
city,
min(gold),
min(silver),
min(normal),
min(timestamp)
FROM cities
GROUP BY city, side
ORDER BY min(timestamp)
当您使用它时,MySQL和SQLite(以及任何其他数据库)都返回相同的结果:SQLFiddle for MySQL,SQLFiddle for SQLite。
<强>更新强>: 此语句将在符合标准的SQL中执行您想要的操作:
SELECT
c.period,
g.side,
g.city,
c.gold,
c.silver,
c.normal,
g.timestamp
FROM cities c,
(SELECT
side,
city,
max(timestamp) AS timestamp
FROM cities
GROUP BY city, side) g
WHERE c.side = g.side
AND c.city = g.city
AND c.timestamp = g.timestamp
ORDER BY c.timestamp
答案 1 :(得分:1)
在没有任何聚合函数的情况下(我在这里专门谈论MySQL),使用GROUP BY子句是不合适的,毫无意义的。也许您打算使用DISTINCT运算符。