【问题标题】:SQL: How to select persons with at least N comments?SQL:如何选择至少有 N 条评论的人?
【发布时间】:2015-05-13 19:34:51
【问题描述】:

我有一个简单(我想)的问题,这让我很困惑(我不是 SQL 专家,你很快就会看到...:-)。

我有一个表person,其中字段idname,还有一个表comment,字段idid_persontext

---------------
 table: person
---------------
 id | name
---------------

---------------------------
 table: comment
---------------------------
 id | id_person | text
---------------------------

cmets 与person.id 上的人员相关联 => comment.id_person
每个人可以拥有多个 cmets。
我宁愿不保存任何表中的 cmets 数量。

问题是:如何选择所有至少有 N 个 cmets 的人?

这是我现在正在尝试的,但它当然是错误的......:

SELECT * FROM person WHERE (SELECT COUNT(*) FROM comment WHERE id_person = 2) >= N

P.S.:我目前正在使用 sqlite,但标准 SQL 答案很好......

【问题讨论】:

  • “这是我现在正在尝试的,但它当然是错误的”,是什么让你说它是错误的?
  • '因为我必须确定一个特定的 'id_person',但我需要所有人... :-( 如您所见,我对 SQL 很困惑... :-(跨度>
  • 不用担心。我在我的答案中包含了一个版本,应该可以解决你的问题。除此之外,这是一个非常好的开始,而且很可能是我会做的。

标签: sql sqlite


【解决方案1】:

我不确定你的尝试有什么问题。您对 ID 进行硬编码,但如果您只是将其换掉,应该没问题。

SELECT *
FROM person
WHERE (SELECT COUNT(*)
       FROM comment
       WHERE id_person = person.id) >= N

另一种解决方案是使用GROUP BY 子句,这很难知道(如果性能是一个问题,您应该尝试每个解决方案,或者至少检查查询计划):

SELECT *
FROM person
WHERE id IN (SELECT id_person
             FROM comment
             GROUP BY id_person
             HAVING COUNT(*) >= N)

INNER JOIN 相比,我喜欢在这里使用IN 子句,因为它可以让您执行SELECT *,就像您在示例中所做的那样。当然,这样做可以sometimes not be ideal,但听起来它适合您的情况。

当然,在每一个中,您都必须将N 替换为参数或文字值。

【讨论】:

    【解决方案2】:

    最简单的方法是像这样使用group byhaving 子句

    select p.name 
    from   person p
           inner join comment c on c.id_person = p.id
    group by
           p.name
    having count(*) = 2
    

    作为旁注:我会将您的列重命名为

    ---------------------------
    table: person
    ---------------
     id_person | name
    ---------------
    
    ---------------------------
     table: comment
    ---------------------------
     id_comment | id_person | text
    ---------------------------
    

    为了明确哪些列是相互关联的。有一天,您会遇到一个新的数据库模式,其中名称不匹配,您必须求助于查找外键关系来解决问题。相信我,这并不好玩。

    【讨论】:

    • 我认为 OP 想要的是 >= 而不是 =。此外,我个人对 id 列没有任何问题,只要外键足够具体(因为它们似乎已经在这种情况下)。从我所看到的情况来看,这确实是一种偏好,可以讨论推荐一个而不是另一个 - 这是一个很好的帖子:programmers.stackexchange.com/questions/114728/…
    • @sgeddes - 好帖子,谢谢。对我来说,this answer 确实总结了它并显示了差异。如果您设计和实现了这些表并不重要,您会知道什么是什么,但对于那些必须维护系统的人来说,这会产生很大的不同。通过查看列名(甚至没有 FK)
    • :) -- 您链接到我提供的帖子中的答案 -- 辩论仍在继续(查看答案的 cmets)!在我看来,一个设计良好的具有描述性外键的数据模型通常可以解决这个问题,但我确实听到了你在说什么。不过,作为开发人员,我更喜欢主键之间的通用性,因为它更容易构建代码(例如重用基类)。有趣的辩论!
    • @sgeddes - 我知道,这是故意的 :)。我的大部分职业生涯都在发展,我很幸运能够创建自己的数据模型(并且只需要清理自己的烂摊子)。不过在过去的三年里,我担任了一个支持职位,大部分时间我都必须弄清楚其他人的代码。从那时起,一致的命名(或缺少它) 对我来说有点恼火。我会满足于id 列虽然(但我更喜欢全名:))
    • 感谢您的 cmets 以及您有趣的辩论!是的,我想要>=...
    【解决方案3】:
    DECLARE @N  INT--Here I declared variable N, but you could simply hardcode the value instead.
    SELECT @N = 2
    
    select  person.id,
            person.name 
    from person 
    INNER JOIN comment ON person.id = comment.id_person
    GROUP BY person.id,
             person.name 
    HAVING COUNT(comment.id) >= @N
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-10
      • 2015-04-17
      • 2020-05-28
      • 1970-01-01
      相关资源
      最近更新 更多