2014-06-05 49 views
5

有没有一种方法可以由一个唯一的(主键)分组,本质上给出了一个隐式的保证,该表中的其他列将被很好地定义?GROUP BY唯一的主键,但选择其他值

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有点慢。如果我从GROUP BY中删除nodes.node_label,则它的运行速度会快大约10倍(根据EXPLAIN,这是因为之前的一个联接先前没有使用索引)。

我们在迁移到Postgres的过程中,因此所有新语句应该是与的MySQL Postgres的时候可能不兼容。现在在Postgres中,原始语句运行得很快,但新语句(使用减少的分组)将不会运行(因为Postgres更严格)。在这种情况下,这是一个错误的错误,因为该声明实际上是明确定义的。

是否有一种语法可以让我们在两个平台上运行相同的语句,同时让MySQL只用一列来提高速度?

+3

'在这种情况下,这是一个虚假的错误,因为该声明实际上是很好defined.'不不不,MySQL的接受weirds GROUP BY的事情(带有不可预知的结果),所有其他DBMS都强迫您获得可预测的结果(通常很有用)。要找到解决方案,我宁愿开展索引管理,以避免MySql缓慢! –

+0

@RaphaëlAlthaus通常这是真的,但通过主键(或任何'UNIQUE'键)进行分组可确保同一个表中的所有其他值都定义良好。 – Dave

+0

但我怀疑它是如何工作的。我不认为查询扫描和解析检查主键/唯一键。 (查询优化/执行策略)... –

回答

0

你可以尝试将其他列到聚集:

SELECT myPrimaryKey, MAX(otherThing) 
FROM myTable 
GROUP BY myPrimaryKey 
+0

我喜欢这个技巧,现在我会使用它。但正如RichardHuxton指出的,我期待的行为在Postgres 9.1+中是允许的,所以作为一个更持久的解决方案,我会要求更新测试数据库。 – Dave

+0

当我只需要投影主键时,应该做什么? –

1

在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?

0

在最近的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