SQL查询 - 尝试避免结果集中的重复数据?

时间:2012-01-14 12:26:49

标签: sql duplicates duplicate-data duplicate-removal

这是一个我一直想知道的问题。我将尝试通过一个例子来解释,但这是一个普遍的问题。

假设您有两张桌子:

  1. 用户,其中包含用户的名字,姓氏......,
  2. 帖子,用于保存用户撰写的帖子,其中包含标题,文字等字段......
  3. 现在,假设我想要显示过去24小时内创建的所有帖子。在此表中,我想显示创建此帖子的用户的名字,姓氏.......查询可能类似于:

    SELECT ... FROM posts,users WHERE posts.user_id = users.id AND [last 24 hours]

    现在,问我的问题。由于一个用户很可能在过去24小时内创建了多个帖子,因此我们基本上一遍又一遍地检索他/她的名字,姓氏......换句话说,上面查询的结果集包含重复数据(但不包含重复行)。

    不是更好:

    1. SELECT ... FROM posts WHERE [last 24 hours]
    2. SELECT ... FROM id为IN的用户(SELECT DISTINCT user_id FROM发布WHERE [过去24小时])
    3. 在应用程序级别或在sql过程中将第一个查询的结果与第二个查询的结果进行映射,以找出帖子的名字,姓氏,......如果标识符(主键)可以很容易地完成)是某种哈希映射,数组或类似的索引/键。
    4. 我知道这是一个非常普遍的问题,但欢迎任何见解。谢谢!

3 个答案:

答案 0 :(得分:2)

任何一种方法都应该有效,但是你找到了重要的部分:

在应用程序级别执行。

对我来说,我会提取重复数据,以便结果集的每一行都包含我需要的所有数据。 SQL在JOIN处更有效,并且设置操作比几乎任何声明性语言都要高。

如果将数据保存在一起,如果需要,您可以更轻松地将其分解为下游,并且您只需要拨打一次数据库而不是两次。

随着重复数据的增长,这种好处逐渐减少。如果它只是几个领域,那不是一个很大的影响。如果它是数十个冗余数据领域,性能差异将更加明显。

对于您的具体示例,在单个查询中完成所有操作要好得多。

如果遇到困难,您可以在应用程序级别消除重复,但与进行多个数据库调用相比,同一用户多次返回的2或3个附加字段不会非常重要。

答案 1 :(得分:0)

我认为最好的解决方案可能是选择用户,whitch有24小时的消息,而不是按用户ID选择消息。

1. step:

SELECT DISTINCT id, first_name, last_name
FROM users INNER JOIN
posts ON posts.user_id = users.id
WHERE [last 24 hours]

2. step:

SELECT *
FROM posts
WHERE user_id = @userId AND [last 24 hours]

这种方式会导致更多数据库调用但内存使用量减少,因为您一次只为1个用户检索邮件。

答案 2 :(得分:0)

最佳解决方案取决于每个表中的行数以及每个用户每天的帖子数。

如果帖子和用户数量相对较少,那么一次性选择帖子和用户就可以了。

如果每个用户的用户数和帖子数很少,最好使用第二个选项单独选择它们。首先,您将选择过去24小时内的帖子,然后您将选择这样的作者:

SELECT users.id, first_name, last_name
FROM users
LEFT JOIN posts ON users.id = user_id
WHERE [posts in the last 24 h]