【问题标题】:Very complex Group By / Unique / Limit by SQL-command非常复杂的 Group By / Unique / SQL 命令限制
【发布时间】:2010-10-22 14:54:26
【问题描述】:

实际上我什至不知道如何称呼它:P,但是...

我有一张桌子,我们称之为“上传”

id    owner    date
-----------------------------
0     foo      20100101120000
1     bar      20100101120300
2     foo      20100101120400
3     bar      20100101120600
..    ..       ..
6     foo      20100101120800

现在,当我会做类似的事情时:

SELECT id FROM uploads ORDER BY date DESC

这将导致:

id    owner    date
-----------------------------
6     foo      20100101120800
..    ..       ..
3     bar      20100101120600
2     foo      20100101120400
1     bar      20100101120300
0     foo      20100101120000

问题:很好,但是,我想更进一步。因为现在,当你要建立一个时间线时(我做了:P),你会被说 foo 和 bar 上传了一些东西的消息“垃圾邮件”。我想对它们进行分组并在日期字段返回第一个时间限制为“500”的结果。

我需要什么样的 SQL 命令会导致:

id    owner    date
-----------------------------
6     foo      20100101120800
3     bar      20100101120600
0     foo      20100101120000

然后,在那之后,我可以在 5 分钟的时间范围内对每条记录执行调用以获取关联记录(这是 id=6 的示例):

SELECT id FROM uploads WHERE date>=20100101120800-500 ORDER BY date DESC

现在有人知道我应该如何做第一步吗? (因此限制/分组结果)

(顺便说一句。我知道当我想使用它时,我应该将每个日期 (YmdHis=60) 转换为 Unix 时间 (=100),但我不需要 5 分钟 正好是 5 分钟,有时可能会少一分钟……)

【问题讨论】:

    标签: mysql grouping limiting


    【解决方案1】:

    我不太清楚你想要得到的结果,即使是你的例子。也许有四舍五入和分组依据。

    SELECT max(id) max_id,owner, (ROUND(date/500)*500) date_interval, max(date) date
    FROM uploads GROUP BY date_interval,owner
    

    您可能想要使用 FLOOR 或 CEILING 而不是 ROUND,这取决于您想要什么。

    【讨论】:

    • 这正是我的意思。我现在使用“SELECT id FROM uploads GROUP BY ROUND(UNIX_TIMESTAMP(date)/3600), owner”。我正在使用 3600,因为我认为 1 小时比 5 分钟都好。在 Reinierpost 提到“间隔”之后,我开始搜索“MySQL Group By Interval”,我发现:forum.percona.com/index.php/t/748,这非常有帮助!无论如何,非常感谢 Reinierpost、Symcbean 和 Brent!
    【解决方案2】:

    标准 SQL 不能很好地处理间隔。 您将需要对表进行自连接以比较不同元组的日期。 这样,您可以轻松找到日期相距不超过 500 的所有元组对。 但是,您确实希望将日期聚集在相距不超过 500 的集合中 - 据我所知,这根本无法用 SQL 表示。

    您可以做的事情非常相似:将总时间间隔分成固定的 500 个单位范围,然后根据它们所在的间隔对表中的所有元组进行聚类。为此,您首先需要一个表或带有间隔开始时间的查询结果;这可以使用表上的 SQL 查询和一个函数来创建,该函数要么将时间戳“四舍五入”到其间隔中的开始时间,要么计算其间​​隔序列号。然后作为第二步,您可以使用该结果加入表,以根据相应的开始时间对其时间戳进行分组。我不能给出 SQL,因为它依赖于 DBMS,我当然不能告诉你这是否是在你的情况下完成你想要的最好的方法。

    【讨论】:

      【解决方案3】:

      使用内联视图?例如像

      SELECT u1.* 
      FROM uploads u1,
      (SELECT date 
          FROM uploads u2
          WHERE u2.owner='foo') datum_points
      WHERE u1.date BETWEEN datum_points.date
          AND DATE_ADD(datum_points.date INTERVAL 5 MINUTES)
      

      应该在 'foo' 发帖后 5 分钟内返回所有发帖。

      【讨论】:

        猜你喜欢
        • 2012-09-08
        • 1970-01-01
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-23
        • 1970-01-01
        相关资源
        最近更新 更多