0

我有一个数据库,其中包含一组人之间发送的一堆消息,每条消息都有一个日期时间格式的时间戳。我正在从该日期时间列中提取时间,并尝试将其与静态时间戳进行比较,以查看每个用户在该时间之后发送了多少条消息。我使用的代码如下:

SELECT sender_id, SUM(CASE WHEN DATE_FORMAT(created_at,'%H:%i:%s')>CAST('17:00:00' AS time) THEN 1 ELSE 0 END) AS no_msgs_afterhours GROUP BY sender_id;

有趣的是,这在 MariaDB 数据库实例中完美运行,但在 MySQL 实例中它给了我这个错误:

错误 1267 (HY000): 非法混合排序规则 (utf8_general_ci,COERCIBLE) 和 (latin1_swedish_ci,NUMERIC) 用于操作“>”

MariaDB 实例版本为 5.5.32,MySQL 实例版本为 5.5.29。这可能是MySQL版本问题吗?我在网上读到 MySQL 4.1.8 及更早版本曾经存在类似的排序规则问题,但这不应该适用于此。

4

1 回答 1

1

这是因为您对服务器和数据库/连接有不同的默认排序规则。该DATE_FORMAT()函数生成一个 latin1_swedish_ci 排序规则并将其与数据库排序规则进行比较。

像这样写它,它会工作:

SELECT sender_id, SUM(CASE WHEN TIME(created_at) > CAST('17:00:00' AS time) THEN 1 ELSE 0 END) AS no_msgs_afterhours GROUP BY sender_id;

注意:您缺少 FROM 子句;)

您甚至不需要转换为时间:

SELECT sender_id, SUM(CASE WHEN TIME(created_at) > '17:00:00' THEN 1 ELSE 0 END) AS no_msgs_afterhours GROUP BY sender_id;

你可以看到它是如何与这个小测试脚本一起工作的:

create table foo (dt datetime, ts timestamp);
insert into foo values (NOW(), NOW());

/*doesn't work*/
SELECT 
CASE WHEN DATE_FORMAT(ts,'%H:%i:%s')>CAST('17:00:00' AS time) THEN 1 ELSE 0 END 
FROM foo;

/*works*/
SELECT 
CASE WHEN DATE_FORMAT(ts,'%H:%i:%s')>'17:00:00'  THEN 1 ELSE 0 END 
FROM foo;

/*works*/
SELECT 
CASE WHEN TIME(ts)>'17:00:00' THEN 1 ELSE 0 END 
FROM foo;

/*works*/
SELECT 
CASE WHEN TIME(ts)>CAST('17:00:00' AS time) THEN 1 ELSE 0 END 
FROM foo;
于 2013-09-09T19:14:11.197 回答