我有关于GROUP_CONCAT()的以下问题:
我的表格简化了以下格式:
| userId | visitTime | position |
1 TIME1 A
1 TIME2 B
1 TIME3 B
1 TIME4 B
1 TIME5 A
1 TIME6 C
使用我当前的sql语句:
Select group_concat(position) from Table where userId=1
我收到了
A,B,B,B,A,C
如何对group_concat进行分组,以便得到如下结果:
A,B,A,C
提前致谢!
编辑:
我喜欢拥有真实的连续位置序列,其中只应对下次visitTime中相同位置的多次出现进行分组。
EDIT2:
我的预期输出是 A,B,A,C
例如:用户1从A移动到B, 在那里,他留在B超过1次入场:B,B,而不是他回到A,之后他去了C.
我只想得到他使用的路径:
从A到B到A到C
因此,如果用户移动到另一个位置,则应该识别,但他可以再次移回。
答案 0 :(得分:2)
以下是语法:
Select group_concat(distinct position order by position)
from Table
where userId=1
答案 1 :(得分:1)
首先,要实现这一点,您需要一个唯一的ID来向您显示记录的顺序(否则您的请求无法实现)。所以我要在你的表中添加id
列,如下所示:
| id | userId | visitTime | position |
1 1 TIME1 A
2 1 TIME2 B
3 1 TIME3 B
4 1 TIME4 B
5 1 TIME5 A
6 1 TIME6 C
现在提取最终字符串的查询:
SELECT GROUP_CONCAT(t3.position ORDER BY t3.id)
FROM (
SELECT t1.*, ((
SELECT position
FROM Table
WHERE
id > t1.id
AND
userId = 1
ORDER BY id
LIMIT 1
)) AS following_position
FROM Table t1
WHERE
t1.userId = 1
) t3
WHERE
t3.position <> t3.following_position OR t3.following_position IS NULL
这是不使用子查询的相同查询(我期望以这种方式获得更好的性能,但我不确定它中是否有太多的NULL):
SELECT GROUP_CONCAT(t3.position ORDER BY t3.id)
FROM (
SELECT t1.*, MIN(t2.id) AS following_id
FROM Table t1
LEFT JOIN Table t2 ON (t1.id < t2.id)
WHERE
t1.userId = 1
AND
(t2.userId = 1 OR t2.userId IS NULL)
GROUP BY t1.id
) t3
LEFT JOIN Table t4 ON (t3.following_id = t4.id)
WHERE
t3.position <> t4.position OR t4.position IS NULL
答案 2 :(得分:0)
我很确定你找不到一个很好的MySQL解决方案。
我建议你在你的应用层进行。
答案 3 :(得分:0)
尝试此查询(依赖于每个用户的唯一visitTime
值...)
-- get those elements p1 from your table...
select p1.userId, group_concat(p1.position order by p1.visitTime)
from p p1
-- for which there doesn't exist a successor p2 with the same "position"
where not exists (
select *
from p p2
where p1.userId = p2.userId
and p1.visitTime < p2.visitTime
and p1.position = p2.position
-- for which there doesn't exist any record p3 strictly in between p1 and p2
and not exists (
select *
from p p3
where p2.userId = p3.userId
and p1.visitTime < p3.visitTime
and p2.visitTime > p3.visitTime
)
)
group by p1.userId
请参阅此SQLFiddle中的演示。
注意,在其他数据库中,您可能会使用窗口函数,例如LEAD() OVER()
和LAG() OVER()
,而不是编写上面的怪物......