我有一个用户数据库,他们可以向其他用户发送消息(最多四个),他们发送的消息ID在用户行中。
Name | Email | Msg1 | Msg2 | Msg3 | Msg4
--------+-------------+------+------+------+-----
Pez | me@me.com | 1 | 55 | 42 | 5
Steve | fake@me.com | 0 | 0 | 0 | 0
Leon | josh@me.com | 3 | 0 | 3 | 5
如何在MySQL查询中获取非空或不等于0的消息行的数量,允许我按顺序排序?所以它会返回
Pez | 4 Mesasges
Leon | 3 Messages
Steve | 0 Messages
我的想法是:
order by count(!empty(msg1)+!empty(msg2)+!empty(msg3)+!empty(msg4))
答案 0 :(得分:3)
使用normalized tables可以像
一样简单SELECT Count(*) FROM messages WHERE userid=47
但是使用您的架构尝试类似
的内容SELECT
name,
(msg1<>0) + (msg2<>0) + (msg3<>0) + (msg4<>0) as cMessages
FROM
foo
编辑:Vincent Ramdhanie使用if()的答案并不依赖于MySQL的行为,因为比较结果使用0作为false,使用1作为true。我希望如此。
答案 1 :(得分:2)
select
if(msg1 = 0, 0, 1) +
if(msg2 = 0, 0, 1) +
if(msg3 = 0, 0, 1) +
if(msg4 = 0, 0, 1) as NumMsg,Name
from table
答案 2 :(得分:1)
您最好的选择是normalize your database,如下所示:
Table users: (user_id, name, email)
Table messages: (user_id, msg_number, msg_code)
users
表将user_id
作为主键,而messages
表将在(user_id, msg_number)
上具有复合主键。 msg_number
字段代表1-4消息号(您在列名中表示的数字)。
复合主键可以保证每个用户每个msg_number
只能有一条消息。您可能还想创建check constraint,以便msg_number
始终&lt; = 4.最后,您可能希望将user_id
表中的messages
定义为{{3}到users
表。
请注意,如果用户没有发送消息,则消息表中不应该有msg_code
= 0的行。相反,您应该省略该行。
使用规范化表格,计算每个用户的消息数量非常简单:
SELECT u.name, COUNT(m.msg_number) as num_of_messages
FROM users u
JOIN messages m ON (m.user_id = u.user_id)
GROUP BY u.user_id;
答案 3 :(得分:1)
正如其他人所说,解决问题的正确方法是规范化您的数据库。
您可以从当前架构中获取计数 - 但它有点乱:
SELECT name, (SIGN(msg1)+SIGN(msg2)+SIGN(msg3)+SIGN(msg4))
FROM yourtable
ORDER BY (SIGN(msg1)+SIGN(msg2)+SIGN(msg3)+SIGN(msg4)) DESC;
下进行。