【问题标题】:Semi-Distinct MySQL Query半不同的 MySQL 查询
【发布时间】:2009-03-25 18:29:07
【问题描述】:

我有一个名为 items 的 MySQL 表,其中包含数千条记录。每条记录都有一个user_id 字段和一个created(日期时间)字段。

尝试对SELECT 25 行进行查询,将用户ID 字符串作为条件传递并按created DESC 排序。

在某些情况下,可能只有几个用户 ID,而在其他情况下,可能有数百个。

如果结果集大于 25,我想通过消除重复的 user_id 记录来减少它。例如,如果user_id = 3 有两条记录,则只会包括最近的(根据created 日期时间)。

在我尝试解决方案时,我遇到了麻烦,因为例如,很容易获得 100 个结果集(允许重复的 user_id 记录)或 16 个结果集(使用 GROUP BY唯一的user_id 记录),很难获得 25 个。

一种逻辑方法(可能不是正确的 MySQL 方法)是为每个 user_id 获取最近的记录,然后,如果结果集小于 25,则开始为每个添加第二条记录user_id 直到达到 25 条记录限制(可能需要为每个 user_id 提供第三条、第四条等记录)。

这可以通过 MySQL 查询来完成,还是我需要获取一个大型结果集并使用代码将其缩减到 25 个?

【问题讨论】:

  • 删除重复项的要求是什么。假设您的记录集为 35(带有 dups),但删除 dups 会导致 23。为了获得 25 条记录,哪些 id 将被允许复制?
  • 最近创建的记录,与 user_id 无关。

标签: sql mysql


【解决方案1】:

我认为您尝试完成的操作不可能作为 SQL 查询。您希望返回 25 行,无论正常的数据分组是什么,而 SQL 通常对基于数据分组的返回很挑剔。

如果您想要一个纯基于 MySQL 的解决方案,您可以使用存储过程来完成此操作。 (在 MySQL 5.0.x 及更高版本中受支持。)但是,运行查询以返回所有 100 多行,然后在应用程序中以编程方式对其进行修剪可能更有意义。

【讨论】:

    【解决方案2】:

    这将为您提供每个用户的最新信息 --

    选择用户 ID,创建
    FROM 项目 AS i1
    LEFT JOIN 项目 AS i2
    ON i1.user_id = i2.user_id AND i1.create > i2.create
    i2.id 为空的地方

    他将为您提供每个用户最近的两条记录--

    选择用户 ID,创建
    FROM 项目 AS i1
    LEFT JOIN 项目 AS i2
    ON i1.user_id = i2.user_id AND i1.create > i2.create
    左连接项目是 i3 ON i2.user_id = i3.user_id AND i2.create > i3.create
    哪里 i3.id 为空

    尝试从那里开始工作。

    您可以很好地将其放入存储过程中。

    【讨论】:

    • 啊,gold ol' vim 和它的二合字母。 :)
    【解决方案3】:

    我的意见是使用应用程序逻辑,因为这是您尝试在数据库级别实现的非常多的应用程序层逻辑,即过滤结果以使搜索对最终用户更有用。

    您可以实现一个存储过程(我个人永远不会这样做)或者只是让应用程序来决定哪 25 个结果。

    【讨论】:

      【解决方案4】:

      一种方法是获取每个用户的最新项目,然后是所有用户的最新项目,并限制它。你可以构建病态的例子,这可能不是你想要的,但总的来说应该很好。

      【讨论】:

      • 这是一个很好的简单解决方案。我可以从所有用户中选择一个,如果少于 25 个,则以最近的整体来填补空白,而不考虑欺骗用户。
      【解决方案5】:

      不幸的是,没有简单的方法:(当我为我的公司构建一个报告时,我不得不做类似的事情,该报告会提取记录在数据库中的客户禁用。唯一的问题是断开连接运行并记录每个30 分钟。因此,由于每次断开连接的时间戳都不同,因此行不会不同。我用子查询解决了这个问题。我没有确切的代码了,但我相信这就是我实现它的方式:

      SELECT CORP, HOUSE, CUST, 
          (
              SELECT TOP 1 hsd
              FROM #TempTable t2
              WHERE t1.corp = t2.corp
              AND t1.house = t2.house
              AND t1.cust = t2.cust
          ) DisableDate
      FROM #TempTable t1
      GROUP BY corp, house, cust -- selecting distinct
      

      所以,我的答案是通过使用子查询从查询​​中消除非不同列。不过,可能有更简单的方法来做到这一点。我很想看看其他人的帖子。

      对不起,我一直在编辑这个,我一直在努力寻找更容易展示我所做的事情的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多