如何选择与不存在最小概念的每个组中第一行对应的记录?

时间:2015-06-05 21:25:34

标签: mysql group-by

我的表格遵循以下结构

+--------+---------+---------------------+--------------------+
| userId | loginId | tstamp              | action             |
+--------+---------+---------------------+--------------------+
| 134088 | NE78MEZ | 2014-10-31 13:59:33 | pageview           |
| 134088 | NE78MEZ | 2014-10-31 13:59:53 | pageview           |
| 134088 | NE78MEZ | 2014-10-31 14:00:26 | pageview           |
| 134088 | NE78MEZ | 2014-10-31 14:00:28 | pageview           |
| 134088 | 9T3CgQ7 | 2014-10-31 14:33:27 | pageview           |
| 134088 | 9T3CgQ7 | 2014-10-31 14:33:27 | pageview           |
| 134088 | 9T3CgQ7 | 2014-10-31 14:46:47 | pageview           |
| 134088 | tq69c8F | 2014-10-31 15:09:02 | pageview           |
| 134088 | tq69c8F | 2014-10-31 15:09:40 | ask                |
| 134088 | tq69c8F | 2014-10-31 15:10:34 | tag                |
| 134088 | tq69c8F | 2014-10-31 15:10:38 | tag                |
| 134088 | tq69c8F | 2014-10-31 15:10:45 | tag                |
| 134088 | tq69c8F | 2014-10-31 15:10:59 | rating             |
| 134088 | tq69c8F | 2014-10-31 15:11:09 | rating             |
| 134088 | tq69c8F | 2014-10-31 15:11:12 | pageview           |
| 134088 | tq69c8F | 2014-10-31 15:11:20 | tag                |
| 134088 | tq69c8F | 2014-10-31 15:11:29 | tag                |
| 134088 | tq69c8F | 2014-10-31 15:13:55 | rating             |
+--------+---------+---------------------+--------------------+

对于每个用户(我在下面的示例中只有一个用户),我有不同的登录ID,它们是随机生成的ID,代表不同的登录会话。对于这样的随机生成的字符串,minimum(loginId)的概念没有意义。但对于每个用户,我想选择与第一个loginId相对应的所有记录。

所以,我希望输出类似于:

+--------+---------+---------------------+--------------------+
| userId | loginId | tstamp              | action             |
+--------+---------+---------------------+--------------------+
| 134088 | NE78MEZ | 2014-10-31 13:59:33 | pageview           |
| 134088 | NE78MEZ | 2014-10-31 13:59:53 | pageview           |
| 134088 | NE78MEZ | 2014-10-31 14:00:26 | pageview           |
| 134088 | NE78MEZ | 2014-10-31 14:00:28 | pageview           |
对于具有userId 134088的用户,

,然后是列表中的下一个用户。

我能想到的一种方法是创建一个名为session id的列,它是随机生成的loginId的“数字”版本,并使用带有where session=1子句的group by userId。有没有办法在不创建这个冗余列的情况下解决这个问题?

我正在尝试在mysql中执行此操作

1 个答案:

答案 0 :(得分:2)

您可以通过查找最小时间戳然后选择与之关联的所有登录来执行此操作。使用窗口/分析函数会更容易,但在MySQL中:

select t.*
from mytable t join
     (select t2.userid, substring_index(group_concat(t2.loginid order by timestamp), ',', 1) as firstlogin
      from mytable t2
      group by t2.userid
     ) t2
     on t.userid = t2.userid and t.login = t2.firstlogin;

substring_index() / group_concat()是MySQL中的一个技巧,用于获取与第一个时间戳关联的登录信息。这节省了一些额外的join逻辑或者必须使用变量。