如何使用GROUP BY以便按特定列排序?

时间:2015-08-12 08:56:30

标签: mysql group-by

我需要从下表中获取所有最新登记入住时间和退房时间的清单:

Table: checkin_times

    +----------+-------------------------+---------------------+
    |  Person  | in_time                 | out_time            |
    +----------+-------------------------+---------------------+
    |  Bob     | 2015-08-10 07:15:00     | 2015-08-10 17:15:00 |
    |  Bob     | 2015-08-12 07:00:00     | NULL                |
    |  Geoff   | 2015-08-12 07:40:00     | 2015-08-12 17:40:00 |
    |  Bob     | 2015-08-11 07:15:00     | 2015-08-12 17:15:00 |
    |  Geoff   | 2015-08-10 07:00:00     | 2015-08-12 17:00:00 |
    +----------+-------------------------+---------------------+

(显然NULL表示此人尚未结帐。)

我对最新的条目不感兴趣。因此,对于此示例,输出应为:

+----------+-------------------------+---------------------+
|  Person  | in_time                 | out_time            |
+----------+-------------------------+---------------------+
|  Bob     | 2015-08-12 07:00:00     | NULL                |
|  Geoff   | 2015-08-12 07:40:00     | 2015-08-12 17:40:00 |
+----------+-------------------------+---------------------+

我尝试过以下SQL:

SELECT person, MAX(in_time) AS in_time, MAX(out_time) AS out_time 
FROM checkin_times  
GROUP BY person
ORDER BY person;

但它无法正确处理NULL并返回out_time的最新实际日期。

理想情况下,我希望GROUP BY的顺序在确定序列时只考虑in_time

4 个答案:

答案 0 :(得分:2)

如果我理解正确,您将尝试在最近的in_time中获取每个人的所有列值。

然后首先获取最新的in_time并将它们连接到所有记录上。

示例

mysql> select ct.person, ct.in_time, ct.out_time
    ->   from checkin_times ct
    ->   right join ( select person, max( in_time ) as in_time
    ->                 from checkin_times group by person ) it
    ->          on ct.person = it.person and ct.in_time=it.in_time;
+--------+---------------------+---------------------+
| person | in_time             | out_time            |
+--------+---------------------+---------------------+
| Bob    | 2015-08-12 07:00:00 | NULL                |
| Geoff  | 2015-08-12 07:40:00 | 2015-08-12 17:40:00 |
+--------+---------------------+---------------------+
2 rows in set (0.04 sec)

SQL Fiddle Demo

答案 1 :(得分:0)

试试这个

SELECT ct.person, ct1.in_time, ct2.out_time 
FROM checkin_times AS ct
INNER JOIN (
    SELECT MAX(in_time) AS in_time, person 
    FROM checkin_times
    GROUP BY person
) AS ct1 ON ct1.person = ct.person
INNER JOIN (
    SELECT out_time, in_time, person 
    FROM checkin_times
) AS ct2 ON (ct2.person = ct1.person AND ct2.in_time = ct1.in_time)
ORDER BY ct.person

答案 2 :(得分:0)

使用CASE语句并使用DATE()CURDATE()

SELECT person, MAX(in_time) AS in_time, MAX(out_time) AS out_time 
FROM checkin_times
GROUP BY person
ORDER BY person, 
CASE WHEN out_time IS NULL
THEN DATE()
ELSE out_time
END;

答案 3 :(得分:0)

试试这个

SELECT person, MAX(in_time) AS in_time, out_time AS out_time 
FROM checkin_times  
GROUP BY person
ORDER BY person;