根据MySQL中的特定情况查找列的平均长度

时间:2013-09-10 22:10:38

标签: mysql case average

我有一个用户表和另一个他们发送的消息表,我正在尝试查找消息的平均长度以及用户退休时消息的平均长度。如果我试试这个:

SELECT u.id, 
AVG(LENGTH(m.body)) AS avg_msg_length, 
AVG(LENGTH(CASE m.is_retired WHEN true THEN m.body ELSE NULL END)) AS avg_msg_length_retired 
FROM Users u LEFT OUTER JOIN Messages m 
ON u.id = m.sender_id 
GROUP BY u.id;

在结果中,我得到的平均长度很好,但退休人员的平均长度只是一列NULL。

如果我试试这个:

SELECT u.id, 
AVG(LENGTH(m.body)) AS avg_msg_length, 
AVG(LENGTH(CASE m.is_retired WHEN "true" THEN m.body ELSE NULL END)) AS avg_msg_length_retired 
FROM Users u LEFT OUTER JOIN Messages m 
ON u.id = m.sender_id 
GROUP BY u.id;

我明白了,

  

ERROR 1054(42S22):'字段列表'中的未知列'“true”'。

我发现这非常奇怪,因为is_retired字段是varchar。

我是否在LENGTH内使用了CASE WHEN?我尝试了第二种形式的CASE WHEN:

 AVG(LENGTH(CASE WHEN m.is_retired=true THEN m.body ELSE NULL END)) AS avg_msg_length_retired 

和,

AVG(LENGTH(CASE WHEN m.is_retired="true" THEN m.body ELSE NULL END)) AS avg_msg_length_retired 

并获得与上述相同的结果。

1 个答案:

答案 0 :(得分:1)

我更喜欢length()中的case

SELECT u.id, 
       AVG(LENGTH(m.body)) AS avg_msg_length, 
       AVG(CASE WHEN m.is_retired = 'Y' THEN LENGTH(m.body) END) AS avg_msg_length_retired 
FROM Users u LEFT OUTER JOIN
     Messages m 
     ON u.id = m.sender_id 
GROUP BY u.id;

'Y'应该是任何字符或字符串表示真相。

您的查询的问题在于您将字符表达式(is_retired)与数字表达式(true)混合在一起。与类型保持一致。

例如,这评估为false:

 select 'true' = true;

但这评估为真:

select 1 = true;