0

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

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;

我明白了,

错误 1054 (42S22):“字段列表”中的未知列“真”。

我觉得这非常奇怪,因为 is_retired 字段是一个 varchar。

我是否在 LENGTH 内错误地使用了 CASE?我也尝试了 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 

并得到与上面相同的结果。

4

1 回答 1

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;
于 2013-09-10T22:20:57.177 回答