计算MySQL中非空的字段数

时间:2010-03-25 11:02:03

标签: php mysql

我有一个用户数据库,他们可以向其他用户发送消息(最多四个),他们发送的消息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)) 

4 个答案:

答案 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;

下进行。