【问题标题】:SQL - group session log entries and order the groups by session start timeSQL - 分组会话日志条目并按会话开始时间对组进行排序
【发布时间】:2011-06-21 14:47:45
【问题描述】:

我是 SQL 新手,不知道如何进行以下查询。当然,我错过了一个非常基本的表达方式,但我自己却找不到。

我有下表,用于存储应用程序日志条目。每个条目都有一个记录时间戳、创建该条目的应用程序的标识符、应用程序实际执行的操作以及该应用程序实例的给定会话的唯一 ID。


item_id item_datetime 应用操作 session_id
1 2011-06-20 19:01:04 开始 23B6C531-6D38-4E47-A887-10B945B48BD9
2 2011-06-20 19:01:05 b 开始 7E6D0F55-4280-46DF-A829-F6821FF028D5
3 2011-06-20 19:03:45 b 工作 7E6D0F55-4280-46DF-A829-F6821FF028D5
4 2011-06-20 19:09:33 一份工作 23B6C531-6D38-4E47-A887-10B945B48BD9
5 2011-06-20 19:27:00 退出 23B6C531-6D38-4E47-A887-10B945B48BD9
6 2011-06-20 19:50:00 c 开始 12345678-1234-4321-1234-109876543210
7 2011-06-20 19:50:01 c 退出 12345678-1234-4321-1234-109876543210
8 2011-06-20 19:50:22 b 退出 7E6D0F55-4280-46DF-A829-F6821FF028D5

在此示例中,有 3 个不同的应用程序“a”、“b”和“c”同时执行,每个会话与其他会话重叠。我需要的是按会话分组的列表,会话(结果组)应按会话开始时间排序。 对于上面的示例表,我希望得到以下结果:


item_id item_datetime 应用操作 session_id
1 2011-06-20 19:01:04 开始 23B6C531-6D38-4E47-A887-10B945B48BD9
4 2011-06-20 19:09:33 一份工作 23B6C531-6D38-4E47-A887-10B945B48BD9
5 2011-06-20 19:27:00 退出 23B6C531-6D38-4E47-A887-10B945B48BD9

2 2011-06-20 19:01:05 b 开始 7E6D0F55-4280-46DF-A829-F6821FF028D5 3 2011-06-20 19:03:45 b 工作 7E6D0F55-4280-46DF-A829-F6821FF028D5 8 2011-06-20 19:50:22 b 退出 7E6D0F55-4280-46DF-A829-F6821FF028D5

6 2011-06-20 19:50:00 c 开始 12345678-1234-4321-1234-109876543210 7 2011-06-20 19:50:01 c 退出 12345678-1234-4321-1234-109876543210

我尝试使用 order by 进行分组,但问题是结果的排序是基于 session_id 的字母顺序 - 但这不是我需要的,会话 id 的唯一性很重要,它们的“价值”确实没关系。

【问题讨论】:

  • 会话 id 的唯一性是什么意思,cos,当您使用 order by 时,值将按字母顺序排序,但随后您将获得所需的结果 rt。即三个会话 id 将在一起,然后将时间添加到 order by 将对您的时间进行排序
  • 这是 MySQL 服务器上 MyISAM 类型的表。
  • @Balanivash,关于唯一性,我的意思是:在这种情况下,SID 的值或字母顺序无关紧要(我不一定要显示 SID),这些应该只是基础对整体进行分组。如果我先按 SID 排序,然后按日期排序,那么像 AAAA-... 这样的 session_id 将首先出现,它的 3 个条目一起按日期排序。但是会话 AAAA-... 可能已有 2 年历史,因此任何基于 SID 的字母顺序都是无用的。

标签: sql group-by sql-order-by


【解决方案1】:

您可以使用子查询来查找第一次看到会话的日期。这允许您订购会话:

select  yt.item_id
,       yt.item_datetime
,       yt.app
,       yt.action
,       yt.session_id
from    (
        select  session_id
        ,       min(item_datetime) as MinDate
        from    YourTable
        group by
                session_id
        ) sessions
left join
        YourTable yt
on      yt.session_id = sessions.session_id
order by
        session.MinDate
,       yt.item_datetime

【讨论】:

  • 这几乎可以工作。一种奇怪的行为是它在 session_id 列中总是返回“0”(我不明白为什么)。第二个问题是它每个会话只列出 1 个条目。我通过将 GROUP BY session_id 添加到内部 SELECT 中对其进行了修改,如下所示:` ( select session_id , min(item_datetime) as MinDate from YourTable group by session_id ) sessions`
  • @cactusdev:关于缺少的group by,您是对的,我已将其添加到答案中。不知道是什么导致“0”出现在session_id 列中。
【解决方案2】:

在我看来,您不想分组而只想排序吗? 所以:

SELECT item_id,item_datetime,app,action,session_id
FROM Table
ORDER BY app,item_datetime

【讨论】:

  • 不,这将首先按应用程序对条目进行排序。到目前为止,我有一个包含大约 10k 个整体的表,上面应用了上述查询,我​​会在前几十个屏幕页面上看到只有应用程序“A”的条目。但是,我希望看到会话整体,分组为会话(首先显示最新会话),以及在其相关会话组内按日期排序的整体。
【解决方案3】:

只需添加子句

ORDER BY `session_id` ASC , `item_datetime` ASC

到您的 SQL 查询

【讨论】:

  • 这将按字母顺序按 session_id 排序,然后按日期排序,但是像 AAAA-... 这样的 SID 首先出现,或者甚至 ZZZZ-... 如果首先出现,可能是多年前记录的。我需要最先出现的最新会话,其条目按日期时间排序顺序列出。
  • 然后order by item_datetimegroup by session_id
【解决方案4】:

你有没有尝试过这样的事情?

SELECT
  *
FROM
  yourTable
ORDER BY
  app,
  session_id,
  item_datetime

这似乎是您所描述的,尽管您说您尝试过仅使用 ORDER BY?

【讨论】:

  • 这不是我需要的。它会首先按应用程序名称按字母顺序对条目进行排序,然后按... 在这里我们可以停止:我需要按 session_id 分组的日期排序列表。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 2020-10-22
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
相关资源
最近更新 更多