Mysql sqlite GROUP BY语句中的奇迹
我有一个表,它是按城市分组的,侧列为唯一的条目,我需要查询每个城市的最新条目,侧组。(较新的条目始终具有较高的时间戳值) 在SQLite中,我可以使用GROUP BY进行作业: 但在MySQL中,它不是这样工作的:Mysql sqlite GROUP BY语句中的奇迹,mysql,sqlite,group-by,Mysql,Sqlite,Group By,我有一个表,它是按城市分组的,侧列为唯一的条目,我需要查询每个城市的最新条目,侧组。(较新的条目始终具有较高的时间戳值) 在SQLite中,我可以使用GROUP BY进行作业: 但在MySQL中,它不是这样工作的: 我想我在这里误用了/滥用了GROUP BY,但是我怎么能对MySQL和SQLite有一个正确的语句呢?在没有任何聚合函数的情况下(我在这里专门谈论MySQL),使用GROUP BY子句是不合适的,也是没有意义的。也许您想使用DISTINCT运算符。在您的示例中,MySQL和SQLit
我想我在这里误用了/滥用了GROUP BY,但是我怎么能对MySQL和SQLite有一个正确的语句呢?在没有任何聚合函数的情况下(我在这里专门谈论MySQL),使用GROUP BY子句是不合适的,也是没有意义的。也许您想使用DISTINCT运算符。在您的示例中,MySQL和SQLite都违反了SQL标准 在标准SQL(所有主要SQL引擎都支持)中,如果在
SELECT
语句中使用groupby
,则SELECT
列表中允许的唯一表达式是groupby
中列出的列,或者聚合函数调用(如count()
,sum()
,avg()
,等等)超过任何其他列
大多数SQL引擎:PostgreSQL、Oracle、MSSQL、DB2严格遵循这一规则——它们不允许使用任何其他语法
然而,MySQL和SQLite都决定在这方面更加松懈,我认为这是一个巨大的错误,也是造成混乱的无尽根源。虽然这似乎有效,但绝对不清楚到底发生了什么。例如,查询生成的SQLite timestamp列看起来与原始表源中的任何内容都不一样
如果你不想有任何惊喜,你应该遵循标准。在您的情况下,这意味着使用如下语句:
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(以及任何其他数据库)都会返回相同的结果:
更新: 此语句将在符合标准的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
它为和生成相同的结果。
(只有一个问题:它假设每个组的时间戳都是唯一的)。结果应该是什么?@bew我希望输出像SQLite的输出一样(即SQLite输出实际上是我想要的),但是使用MySQL引擎。但是这个语句的结果不是我想要的(我问题中的SQLite结果正是我想要的)然后使用标准SQL来获得您想要的—首先,您应该准确地解释您想要的是什么(但不要指向SQLite结果)。如果您仔细考虑一下,将
*
与分组方式一起使用是没有意义的。SQLite和MySQL都允许这样做,但这并不意味着它是可接受的。我需要做的是,获取每个(城市、地区)组的最新条目(具有较大的时间戳值)。“具有最大的时间戳值”是聚合函数max()
,这是groupby
能够理解的。我已经更新了答案,为您提供符合标准的查询。感谢您的声明!