2011-05-18 94 views
2

下表考虑:SQL如何在将多行分组在一起时选择显示哪一行?

CREATE TABLE t 
(
a INTEGER NOT NULL, 
b INTEGER NOT NULL, 
c INTEGER, 
PRIMARY KEY (a, b) 
) 

现在,如果我这样做:

SELECT a,b,c FROM t GROUP BY a; 

我期望有得到的每个不同的值只有一次。但既然我也在问b和c,它会给我一个a的每一个值。因此,如果对于a的单个值,有很多行可供选择,那么我如何预测SQL将选择哪一行?我的测试表明它选择返回b最大的那一行。但那是什么逻辑?这将如何适用于blob或日期字符串或其他任何东西?

我的问题:SQL如何在将多行分组在一起时选择显示哪一行?

BTW:我的特殊问题涉及SQLITE3,但我猜这是一个SQL问题不依赖于数据库管理系统...

+0

在某些SQL RDBMS中,您显示的查询是非法的,因此没有纯粹的“SQL”答案。而在SQL的大多数地方,如果没有ORDER BY子句生效,系统可以自由地重新排列它的输出。 – 2011-05-18 14:43:47

+0

它依赖于RDBMS。例如,SQL Server会将您的SELECT语句标记为错误。 – 2011-05-18 14:44:12

+0

感觉就像破损的语法,必须有一个更好的方法来使用“标准”SQL语句获取所需的数据。也许你需要将其分解成多个查询... – Zachary 2011-05-18 14:49:29

回答

6

这应该不是一个像样的DBMS实际工作:-)

group by子句中不使用任何列应受的聚合功能,如:

select a, max(b), sum(c) from t group by a 

如果它不能在SQLite的抱怨(我也没有直接的理由怀疑你),我'd ju我们把它归结为DBMS的构建方式。从内存中,有一些地方不用担心数据的“纯度”(例如每个列可以容纳多种类型,属于该行/列中数据的类型相交,而不是色谱柱规格)。

+0

然后聚合函数将决定为其他值显示哪些行,即SELECT a,max(b),min(c)FROM t GROUP BY a – Zugwalt 2011-05-18 14:44:56

0

对于您认为这与RDBMS无关的假设,您并不完全正确。大多数RDBMS不允许选择不在GROUP BY子句中的字段。这个例外(据我所知)是SQLite和MySQL。一般来说,你不应该这样做,因为bc的值是非常随意选择的(取决于应用的分组算法)。即使这可能在您的数据库中记录,最好以完全且无歧义地指定结果的方式表达查询

2

我知道的所有SQL引擎都会抱怨您提到的查询错误消息如“b和c出现在字段列表中,但不出现在组列表中”。你只能在集合函数中使用b或c(比如MAX/MIN/COUNT/AVG),否则你将不得不将它们添加到GROUP BY列表中。

0

这不是数据库选择的问题,而是您的数据将要返回的顺序。

默认情况下,您的主键处理您的排序顺序,因为您没有提供。

你可以使用Order By a,c如果这就是你想要的。

+0

其实,我的数据排序不会'不会改变任何事情(在我的特定情况下)到结果。我已经尝试了很多次,它总是选择同一行... – Shawn 2011-05-18 15:03:03