Mysql GROUP BY对投票系统有一个概述

时间:2014-11-03 23:19:51

标签: php mysql

我希望user_id 2概述其他用户在其帐户中执行的最后一项操作,

  1. 投票
  2. 投票否决
  3. 确认
  4. 取消确认
  5. 每次用户执行操作时,右栏中都会添加一行 1 。空白元素用0填充。

    用户是投票人,user_id是投票的人

    | id | user | user_id | up | down | confirm | unconfirm |    date    |
    +----+------+---------+----+------+---------+-----------+------------+
    | 1  |  1   |    2    | 1  |      |         |           | 2014-11-03 |
    | 2  |  1   |    2    | 1  |      |         |           | 2014-11-03 |
    | 3  |  1   |    2    |    |  1   |         |           | 2014-11-03 |
    | 4  |  1   |    2    |    |  1   |         |           | 2014-11-03 |
    | 5  |  1   |    2    |    |  1   |         |           | 2014-11-03 |
    | 6  |  1   |    2    | 1  |      |         |           | 2014-11-03 |
    | 7  |  1   |    2    |    |      |    1    |           | 2014-11-03 |
    | 8  |  1   |    2    |    |      |         |     1     | 2014-11-03 |
    | 9  |  1   |    2    |    |      |    1    |           | 2014-11-03 | //THIS
    | 10 |  1   |    2    | 1  |      |         |           | 2014-11-03 | // THIS
    | 11 |  3   |    2    |    |  1   |         |           | 2014-11-03 |
    | 12 |  3   |    2    | 1  |      |         |           | 2014-11-03 | //THIS
    | 13 |  3   |    2    |    |      |    1    |           | 2014-11-03 | // THIS
    +----+------+---------+----+------+---------+-----------+------------+
    

    输出:上一次上或下,最后一次确认或取消确认每个用户
    - 用户3确认,
    - 用户3 Up,
    - 用户1上,
    - 用户1确认。

    SELECT * FROM table WHERE user_id = 2 GROUP BY .. ORDER BY id DESC
    
    if($data['up'] == '1')
    {
     echo "You have been voted up ... You've earned.."; 
    }
    
    else if($data['down'] == '1')
    {
     echo "You have been voted down ... now you need to.."; 
    }
    
    ...
    

2 个答案:

答案 0 :(得分:4)

要获取对用户采取的最新操作,您可以使用该user_id拉出所有行,按日期降序排序,并限制为1.尝试:

SELECT *
FROM myTable
WHERE user_id = 2
ORDER BY date DESC
LIMIT 1;

另一个注意

如果我可以在这里评论您的表格设计,我真的认为您可以将各种操作放入他们自己的表格中,并在表格中添加一个action_id列。换句话说,它看起来像这样:

action_values

| id |   action  |
+----+-----------+
| 1  | up        |
| 2  | down      |
| 3  | confirm   |
| 4  | unconfirm |

actions

| id | user | user_id | actionID |    date    |
+----+------+---------+----------+------------+
| 1  |  1   |    2    |     1    | 2014-11-03 |
| 2  |  1   |    2    |     1    | 2014-11-03 |
| 3  |  1   |    2    |     2    | 2014-11-03 |
| 4  |  1   |    2    |     2    | 2014-11-03 |
| 5  |  1   |    2    |     2    | 2014-11-03 |
| 6  |  1   |    2    |     1    | 2014-11-03 |
| 7  |  1   |    2    |     3    | 2014-11-03 |
| 8  |  1   |    2    |     4    | 2014-11-03 |
| 9  |  1   |    2    |     3    | 2014-11-03 |
| 10 |  1   |    2    |     1    | 2014-11-03 |
| 11 |  3   |    2    |     2    | 2014-11-03 |
| 12 |  3   |    2    |     1    | 2014-11-03 |
| 13 |  3   |    2    |     3    | 2014-11-03 |

这会使您的查询略有不同,但它肯定会使事情更好地正常化,并有助于避免插入和更新异常。如果您对此感兴趣,请参阅this SQL Fiddle以获取有关查询如何更改的示例。

修改

关于获取最新动作,请参阅我的回答here。它可能有所帮助,因为它讨论了从一个组中获取N个案例,这是你在这里尝试做的事情。您希望从每个组中获取单个最新案例。

所以,我尝试在SQL Fiddle中做到这一点,并尝试了一些试验和错误,但我能够让它工作。不幸的是,我无法找到解决这一问题的方法,但我能够提出这个查询,从每个用户获取最新信息:

SELECT *
FROM myTable m
WHERE(
  SELECT COUNT(*)
  FROM myTable mt
  WHERE mt.user_id = 2
    AND m.user_id = 2
    AND mt.user = m.user
    AND mt.date >= m.date
    AND (mt.up = 1 OR mt.down = 1)
) <= 1
AND (m.up = 1 OR m.down = 1);

简而言之,嵌套部分的作用是获取投票用户2的行,投票用户分组,过滤最大日期,并将结果限制为0或1行。我在这里添加了上下条件,以便它只会在行动向上或向下的情况下拉行。很容易,您可以编写相反的查询来确认/取消确认,并将两者联合起来,如下所示:

(SELECT *
FROM myTable m
WHERE(
  SELECT COUNT(*)
  FROM myTable mt
  WHERE mt.user_id = 2
    AND m.user_id = 2
    AND mt.user = m.user
    AND mt.date >= m.date
    AND (mt.up = 1 OR mt.down = 1)
) <= 1
AND (m.up = 1 OR m.down = 1))
UNION
(SELECT *
FROM myTable m
WHERE(
  SELECT COUNT(*)
  FROM myTable mt
  WHERE mt.user_id = 2
    AND m.user_id = 2
    AND mt.user = m.user
    AND mt.date >= m.date
    AND (mt.confirm = 1 OR mt.confirm = 1)
) <= 1
AND (m.confirm = 1 OR m.confirm = 1));

我正在玩弄如何缩短此查询,但在这个特定时刻它是我所拥有的最好的,它是working,所以希望这会让你再次前进。

答案 1 :(得分:0)

假设您的id是自动增量列,您可以按如下方式获取每个user_id的最新ID。

SELECT MAX(id) AS id
  FROM table
GROUP BY user_id

然后,您可以将该子查询连接到原始表,以提取最近条目的数据。

SELECT a.id, a.user, a.user_id, a.up, a.down, a.confirm, a.unconfirm, a.date
  FROM table AS a
  JOIN (
        SELECT MAX(id) AS id
          FROM table
         GROUP BY user_id
       ) AS b ON a.id = b.id
 WHERE a.user_id = 2

然后,您可以将该查询与您的PHP代码$data['up']等一起使用。这应该为您提供一种展示最新交易的好方法。