Mysql SQL中分区上的字符串Concat?
我想连接周围的行在以下示例中,只有在排名到新columngroup by后周围的2行似乎不起作用,以下是我的数据: 模式MySQL v8.0 来说明我想做什么。我可以使用sum子句对数值求和,如下所示: 问题1 用户id 日期和时间 事件名称 不重要的 琐碎的新 001 2020-12-10 10:00:00 A. 1. 13 001 2020-12-10 10:00:01 B 9 19 001 2020-12-10 10:00:02 C 3. 21 001 2020-12-10 10:00:20 D 6. 20 001 2020-12-10 10:00:40 E 2. 11 002 2020-12-10 10:00:02 A. 2. 15 002 2020-12-10 10:00:09 B 4. 15 002 2020-12-10 10:00:10 C 9 15 002 2020-12-10 10:00:50 D 0 13Mysql SQL中分区上的字符串Concat?,mysql,sql,window-functions,Mysql,Sql,Window Functions,我想连接周围的行在以下示例中,只有在排名到新columngroup by后周围的2行似乎不起作用,以下是我的数据: 模式MySQL v8.0 来说明我想做什么。我可以使用sum子句对数值求和,如下所示: 问题1 用户id 日期和时间 事件名称 不重要的 琐碎的新 001 2020-12-10 10:00:00 A. 1. 13 001 2020-12-10 10:00:01 B 9 19 001 2020-12-10 10:00:02 C 3. 21 001 2020-12-10 10:00:2
您可以通过使用CTEs来解决这个问题:首先计算每个用户id的行号,按日期和时间排序;然后根据行号在该行的最小/最大行号范围内(从行号-之前到行号+之后)将表连接到自身。然后,您可以从联接表中的“事件名称”字段对\u conc进行分组: 设置@before:=2; 设置@after:=2; 以rns为例 选择*, 按用户id划分的卡斯特罗\u编号按日期\u时间排序,签名为rn 从log_表 选择r1.user\u id、r1.date\u time、r1.event\u name、, 组\u CONCATr2.event\u名称分隔符作为事件\u名称\u新建 来自rns r1 在r2.user\u id=r1.user\u id上加入rns r2 r2.rn介于r1.rn-@之前和r1.rn+@之后 按r1.user\u id、r1.date\u time、r1.event\u name分组 按r1.user\U id订购,r1.rn 2之前和2之后的输出:
user_id date_time event_name event_name_new
001 2020-12-10 10:00:00 a abc
001 2020-12-10 10:00:01 b abcd
001 2020-12-10 10:00:02 c abcde
001 2020-12-10 10:00:20 d bcde
001 2020-12-10 10:00:40 e cde
002 2020-12-10 10:00:02 A ABC
002 2020-12-10 10:00:09 B ABCD
002 2020-12-10 10:00:10 C ABCD
002 2020-12-10 10:00:50 D BCD
您可以通过使用CTEs来解决这个问题:首先计算每个用户id的行号,按日期和时间排序;然后根据行号在该行的最小/最大行号范围内(从行号-之前到行号+之后)将表连接到自身。然后,您可以从联接表中的“事件名称”字段对\u conc进行分组: 设置@before:=2; 设置@after:=2; 以rns为例 选择*, 按用户id划分的卡斯特罗\u编号按日期\u时间排序,签名为rn 从log_表 选择r1.user\u id、r1.date\u time、r1.event\u name、, 组\u CONCATr2.event\u名称分隔符作为事件\u名称\u新建 来自rns r1 在r2.user\u id=r1.user\u id上加入rns r2 r2.rn介于r1.rn-@之前和r1.rn+@之后 按r1.user\u id、r1.date\u time、r1.event\u name分组 按r1.user\U id订购,r1.rn 2之前和2之后的输出:
user_id date_time event_name event_name_new
001 2020-12-10 10:00:00 a abc
001 2020-12-10 10:00:01 b abcd
001 2020-12-10 10:00:02 c abcde
001 2020-12-10 10:00:20 d bcde
001 2020-12-10 10:00:40 e cde
002 2020-12-10 10:00:02 A ABC
002 2020-12-10 10:00:09 B ABCD
002 2020-12-10 10:00:10 C ABCD
002 2020-12-10 10:00:50 D BCD
相关子查询可能是最简单的解决方案:
with l as (
select l.*,
cast(row_number() over (partition by user_id order by date_time) as signed) as seqnum
from log_table l
)
select l.*,
(select group_concat(l2.event_name order by l2.date_time separator '')
from l l2
where l2.user_id = l.user_id and
l2.seqnum between l.seqnum - 2 and l.seqnum + 2
) as new_event_name
from l;
如果事件名称为一个字符,则可以消除相关子查询并使用字符串操作:
with l as (
select l.*, full_concat,
cast(row_number() over (partition by user_id order by date_time) as signed) as seqnum
from log_table l join
(select user_id, group_concat(event_name order by date_time separator '') as full_concat
from log_table l
group by user_id
) ll
using (user_id)
)
select l.*, substr(full_concat, greatest(seqnum - 2, 1), least(5, seqnum + 2))
from l;
是一个dbfiddle。相关子查询可能是最简单的解决方案:
with l as (
select l.*,
cast(row_number() over (partition by user_id order by date_time) as signed) as seqnum
from log_table l
)
select l.*,
(select group_concat(l2.event_name order by l2.date_time separator '')
from l l2
where l2.user_id = l.user_id and
l2.seqnum between l.seqnum - 2 and l.seqnum + 2
) as new_event_name
from l;
如果事件名称为一个字符,则可以消除相关子查询并使用字符串操作:
with l as (
select l.*, full_concat,
cast(row_number() over (partition by user_id order by date_time) as signed) as seqnum
from log_table l join
(select user_id, group_concat(event_name order by date_time separator '') as full_concat
from log_table l
group by user_id
) ll
using (user_id)
)
select l.*, substr(full_concat, greatest(seqnum - 2, 1), least(5, seqnum + 2))
from l;
是一个dbfiddle。包含您提供的示例数据和预期输出,我不清楚使用滞后有什么问题?@Nick如果sum可以在没有滞后的情况下做到这一点,我想知道是否可以连接字符串?@Nick例如,我想连接周围的5行5行,然后再连接该行5行到新列,我如何才能做到整洁?不幸的是,没有办法要为字符串连接指定窗口函数。。。你能用更复杂的预期输出数据编辑你的问题吗?e、 g.2之前,1之后,这会让你更容易想出一个好主意solution@Nick请检查更新的问题。根据您提供的样本数据和预期输出,我不清楚使用滞后有什么问题?@Nick如果sum可以在没有滞后的情况下做到这一点,我想知道是否可以连接字符串?@Nick例如,我想连接周围的5行5行,然后再连接该行5行到新列,我如何才能做到整洁?不幸的是,没有办法要为字符串连接指定窗口函数。。。你能用更复杂的预期输出数据编辑你的问题吗?e、 g.2之前,1之后,这会让你更容易想出一个好主意solution@Nick请检查更新的问题。它对我来说太复杂了,让我花些时间来消化它。你能解释一下吗?例如,代码中的一些注释。@LernerZhang看一看,它显示了中间CTE的输出,以及如果去掉分组,从最终查询中得到的结果。那可能会有帮助…@LernerZhang我得走了。。。请在评论中留下任何问题,我会尽快回答。@LernerZhang睡过觉后,我意识到这个问题可以简化。请查看我的编辑。@LernerZhang是的,不再需要计数*,这是原始查询的一部分,在我编辑后不再需要。我已经把它从答案中删除了。您确实需要ORDERBY子句中的r1.rn,否则这些行不会按日期\时间排序。这对我来说太复杂了,让我花一些时间来消化它。你能请求吗
你能解释一下吗?例如,代码中的一些注释。@LernerZhang看一看,它显示了中间CTE的输出,以及如果去掉分组,从最终查询中得到的结果。那可能会有帮助…@LernerZhang我得走了。。。请在评论中留下任何问题,我会尽快回答。@LernerZhang睡过觉后,我意识到这个问题可以简化。请查看我的编辑。@LernerZhang是的,不再需要计数*,这是原始查询的一部分,在我编辑后不再需要。我已经把它从答案中删除了。您确实需要ORDERBY子句中的r1.rn,否则这些行不会按日期\时间排序