我有一个用户表和另一个他们发送的消息表,我正在尝试查找消息的平均长度以及用户退休时消息的平均长度。如果我试试这个:
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
并获得与上述相同的结果。
答案 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;