MySQL的问题!需要从一行中选择唯一值

时间:2010-08-23 11:10:55

标签: sql mysql

我正在创建这个应用程序,重要的是在当天注册一个人是否活跃。我的表结构如下所示:

| Field     | Type        | Null | Key | Default           | Extra          |
+-----------+-------------+------+-----+-------------------+----------------+
| id        | int(11)     | NO   | PRI | NULL              | auto_increment | 
| kid_id    | int(11)     | NO   |     | NULL              |                | 
| status    | varchar(50) | NO   |     | NULL              |                | 
| timestamp | timestamp   | NO   |     | CURRENT_TIMESTAMP |                | 

对我来说重要的是什么;是仅选择时间戳等于当前日期的值。接下来我需要根据kid_id检查最新状态是“活动”还是“非活动”。到目前为止我所知道的是这个。

SELECT kid_id , status , timestamp FROM actions WHERE date(timestamp) = CURDATE() ORDER BY timestamp DESC;

返回以下值:

+--------+----------+---------------------+
| kid_id | status   | timestamp           |
+--------+----------+---------------------+
|      4 | active   | 2010-08-23 12:10:03 | 
|      3 | inactive | 2010-08-23 10:53:18 | 
|      3 | active   | 2010-08-23 10:53:10 | 
+--------+----------+---------------------+

现在唯一的问题是我通过“kid_id”=“3”同时收到活动和非活动状态。 所以我的问题是我如何只从每个kid_id中选择最新状态。

事先感谢你的帮助。很感激。

----------编辑

我会尽力使我的观点更清楚。

这是我的表,因为它现在看起来......

+--------+----------+---------------------+
| kid_id | status   | timestamp           |
+--------+----------+---------------------+
|      3 | inactive | 2010-08-23 18:32:19 | 
|      4 | active   | 2010-08-23 12:10:03 | 
|      3 | active   | 2010-08-23 10:53:10 | 
+--------+----------+---------------------+
3 rows in set (0.00 sec)

我想检索这些值,只检索这些

|      3 | inactive | 2010-08-23 18:32:19 | 
|      4 | active   | 2010-08-23 12:10:03 |

以下建议的所有解决方案都会返回以下值:

|      4 | active   | 2010-08-23 12:10:03 | 
|      3 | active   | 2010-08-23 10:53:10 |

顺便说一句......感谢所有的回复,我很感激所有的帮助。

5 个答案:

答案 0 :(得分:1)

首先,你的WHERE子句应该是

WHERE ... AND status = 'active'

如果您在某一天设置为有效的单个用户可以拥有不同的行,则可以说

SELECT DISTINCT kid, status ...

请注意,这会为您选择的所有内容返回唯一值,因此您不应选择时间戳,因为同一天的同一用户的不同时间戳会再次显示为多行(因为它们是非独特的)

答案 1 :(得分:1)

这应该做

SELECT a1.*
FROM actions AS a1 
   INNER JOIN (SELECT kid_id, MAX(`timestamp`) AS `timestamp` 
                 FROM actions 
                 WHERE date(timestamp) = CURDATE() 
                 GROUP BY kid_id) AS a2 
    ON a2.kid_id = a1.kid_id AND a2.timestamp = a1.timestamp

答案 2 :(得分:0)

使用group by kid_id,它只选择按时间戳排序的最新行

SELECT kid_id , status , timestamp FROM actions WHERE date(timestamp) = CURDATE() GROUP BY kid_id ORDER BY timestamp DESC

答案 3 :(得分:0)

像这样使用group by

 SELECT kid_id , status , timestamp, count(*) as TotalMatches FROM actions WHERE date(timestamp) = CURDATE() GROUP BY kid_id ORDER BY timestamp DESC

[编辑] :仅选择有效状态:

 SELECT kid_id , status , timestamp, count(*) as TotalMatches FROM actions WHERE date(timestamp) = CURDATE() AND status = 'active' GROUP BY kid_id ORDER BY timestamp DESC

答案 4 :(得分:-1)

我今天去了办公室。与此同时,我找到了解决问题的方法。我使用了一个有效的子选择。

最后我的代码看起来有点像 ovais.tariq

这是我的解决方案:

SELECT * 
            FROM (
                SELECT * FROM actions 
                AS a
                WHERE date(timestamp) = curdate() 
                AND timestamp = (
                    SELECT max(timestamp) 
                    FROM actions 
                    AS b
                    WHERE a.kid_id = b.kid_id
                    )
                )
            AS c

感谢大家的帮助:)