有没有办法按唯一(主)键进行分组,本质上是隐含的保证,该表中的其他列将被明确定义?
SELECT myPrimaryKey, otherThing
FROM myTable
GROUP BY myPrimaryKey
我知道我可以将其他列添加到语句(GROUP BY myPrimaryKey,otherThing
)中,但我试图避免这种情况。如果您对此感到好奇,请继续阅读:
我有一个基本上这样做的声明:
SELECT nodes.node_id, nodes.node_label, COUNT(1)
FROM {a couple of joined tables}
INNER JOIN nodes USING (node_id)
GROUP BY nodes.node_id, nodes.node_label
哪个工作正常,但在MySQL中有点慢。如果我从nodes.node_label
中删除GROUP BY
,它的运行速度提高了大约10倍(根据EXPLAIN
,这是因为其中一个早期的连接开始使用索引,而之前它没有)。
我们正在迁移到Postgres,因此所有新语句应尽可能与MySQL和Postgres兼容。现在在Postgres中,原始语句运行得很快,但是新语句(减少的组)将不会运行(因为Postgres更严格)。在这种情况下,这是一个错误的错误,因为该语句实际上是明确定义的。
是否有一种语法我可以使用哪种语言可以在两个平台上运行相同的语句,同时让MySQL只使用组中的一列来提高速度?
您可以尝试将其他列转换为聚合:
SELECT myPrimaryKey, MAX(otherThing)
FROM myTable
GROUP BY myPrimaryKey
在Postgres中(不是在MySQL中),您可以使用DISTINCT ON
为每个值(或值组)选择单个一致的行而不聚合它们:
SELECT DISTINCT ON (n.node_id)
* -- select any or all columns of all joined tables
FROM {a couple of joined tables}
JOIN nodes n USING (node_id)
这为每个node_id
提供了一个单独的任意行。选择一个特定的行,添加:
ORDER BY n.node_id, ... -- what to sort first?
..添加更多ORDER BY
项目来选择一个特定的行。细节:
Select first row in each GROUP BY group?
在更新版本的MySql中,您可能启用了sql_mode=only_full_group_by
,在使用group by
时不允许选择非聚合列,即它强制您使用max()
或avg()
或group_concat()
等函数,有时您只需要任何值。
默认情况下,在MySql 5.7中启用此标志。
启用该标志时,函数any_value()
可用。
通过使用ANY_VALUE()来引用非聚合列,可以在不禁用ONLY_FULL_GROUP_BY的情况下实现相同的效果。
select t.index, any_value(t.insert_date)
from my_table t
group by t.index;
更多信息:https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_only_full_group_by和这里:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html