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 句がありません ;)

time としてキャストする必要さえありません。

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 に答える