mysql有些字段不分组_MySQL-选择不在分组依据中的列

假设您有这样的查询:

SELECT g, v

FROM t

GROUP BY g;

在这种情况下,对于g的每个可能值,mysql选择v的对应值之一。

但是,选择哪种取决于具体情况。

我在某处读到,对于每组g,将保留v的第一个值,其顺序是如何将记录插入表v。

这很丑陋,因为表中的记录应视为元素顺序无关紧要的集合。 这是如此“ mysql-ish” ...

如果要确定保留v的哪个值,则需要为v应用子选择,如下所示:

SELECT g, v

FROM (

SELECT *

FROM t

ORDER BY g, v DESC

) q

GROUP BY g;

这样,您可以定义外部查询处理子查询记录的顺序,因此您可以信任它将为v的单个值选择哪个值v。

但是,如果您需要一些WHERE条件,请非常小心。 如果将WHERE条件添加到子查询中,则它将保留该行为,它将始终返回您期望的值:

SELECT g, v

FROM (

SELECT *

FROM t

WHERE g = '737a8783-110c-447e-b4c2-1cbb7c6b72c9'

ORDER BY g, v DESC

) q

GROUP BY g;

这就是您所期望的,子选择过滤并排序表。 它保留v具有给定值的记录,外部查询返回v和v的第一个值。

但是,如果将相同的WHERE条件添加到外部查询中,则会得到不确定的结果:

SELECT g, v

FROM (

SELECT *

FROM t

-- WHERE g = '737a8783-110c-447e-b4c2-1cbb7c6b72c9'

ORDER BY g, v DESC

) q

WHERE g = '737a8783-110c-447e-b4c2-1cbb7c6b72c9'

GROUP BY g;

令人惊讶的是,一次又一次执行相同的查询时,您可能会获得v的不同值,这很奇怪。 预期的行为是从子查询中以适当的顺序获取所有记录,在外部查询中对其进行过滤,然后选择与上一个示例中相同的记录。 但事实并非如此。

它似乎是随机选择v的值。 如果执行了更多(〜20)次但分布不均匀,则同一查询将为v返回不同的值。

如果不是指定外部WHERE,而是指定如下的HAVING条件:

SELECT g, v

FROM (

SELECT *

FROM t1

-- WHERE g = '737a8783-110c-447e-b4c2-1cbb7c6b72c9'

ORDER BY g, v DESC

) q

-- WHERE g = '737a8783-110c-447e-b4c2-1cbb7c6b72c9'

GROUP BY g

HAVING g = '737a8783-110c-447e-b4c2-1cbb7c6b72c9';

然后,您将再次获得一致的行为。

结论:我建议完全不要依赖这种技术。 如果您确实希望/需要避免在外部查询中使用WHERE条件。 如果可以,请在内部查询中使用它,或者在外部查询中使用HAVING子句。

我用以下数据进行了测试:

CREATE TABLE t1 (

v INT,

g VARCHAR(36)

);

INSERT INTO t1 VALUES (1, '737a8783-110c-447e-b4c2-1cbb7c6b72c9');

INSERT INTO t1 VALUES (2, '737a8783-110c-447e-b4c2-1cbb7c6b72c9');

在mysql 5.6.41中。

也许这只是在新版本中得到修复的错误,如果您有使用新版本的经验,请提供反馈。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值