考虑下表:
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的单个值,有很多行可供选择,我该如何预测SQL将选择哪一行?我的测试显示它选择返回b最大的行。但那是什么逻辑呢?这将如何适用于blob或日期或其他任何字符串?
我的问题:在将多行分组在一起时,SQL如何选择显示哪一行?
btw:我的特殊问题与SQLITE3有关,但我猜这是一个不依赖于DBMS的SQL问题......
答案 0 :(得分:6)
这实际上不应该在一个像样的DBMS中工作: - )
group by
子句中未使用的任何列都应受聚合函数的约束,例如:
select a, max(b), sum(c) from t group by a
如果它没有在SQLite中抱怨(我没有直接的理由怀疑你),我只是把它归结为DBMS的构建方式。从内存来看,有一些领域并不过分担心数据的“纯度”(例如每列都能够容纳多种类型,属于该行/列中数据的类型而不是栏目规范)。
答案 1 :(得分:2)
我所知道的所有SQL引擎都会抱怨您提到的查询,并显示错误消息,例如“b和c出现在字段列表中但不在列表中”。您只能在聚合函数中使用b或c(如MAX / MIN / COUNT / AVG无论如何),否则您将被迫在GROUP BY列表中添加它们。
答案 2 :(得分:0)
你认为这与RDBMS无关是不正确的。大多数RDBMS不允许选择不在GROUP BY
子句中的字段。这个(据我所知)的例外是SQLite和MySQL。通常,您不应该这样做,因为b
和c
的值是相当随意选择的(取决于应用的分组算法)。即使您的数据库中记录了这一点,最好以完全且非模糊地指定结果的方式表达查询
答案 3 :(得分:0)
这不是数据库将选择的内容,而是数据将被返回的顺序。
您的主键是默认处理您的排序顺序,因为您没有提供排序顺序。
您可以使用Order by a,c,如果这是您想要的。