【问题标题】:How to write SQL to return count of occurrences of join data?如何编写 SQL 来返回连接数据的出现次数?
【发布时间】:2015-06-15 16:32:38
【问题描述】:

我有一张房子的桌子和一张窗户的连接表。所以一个房子可以有 0 个或更多的窗户,没有限制(这是一个人为的例子,但它模拟了我正在做的事情)。

我希望能够编写一个 SQL 查询,返回有 0 个窗户的房屋数量、有 1 个窗户的数量、有 2 个窗户的数量等。

即:

# Windows | # Houses
--------------------
0         | 27
1         | 18
2         | 45
3         | 7
etc.

表格超级简单。 Window 有一个“house_id”外键,它引用了 House 表的 ID 字段。

我知道这应该很容易,但对于我的生活我无法弄清楚?

谢谢,

【问题讨论】:

  • 您使用的是哪个 DBMS?甲骨文? Postgres?
  • MySQL,虽然这应该足够标准,我认为任何符合 SQL 的数据库都应该可以工作

标签: mysql sql join count group-by


【解决方案1】:

您可以使用以下查询来获得所需的输出:

SELECT cnt AS `# Windows`, COUNT(*) AS `# Houses`
FROM (
SELECT house_id, COUNT(*) AS cnt
FROM Window
GROUP BY house_id ) t
GROUP BY cnt

这是标准 SQL,因此它应该适用于大多数 RDMBS。

如果您希望 # Windows 字段包含所有可能的数字,从 0 到最大窗口数,那么您必须创建一个计数表和 LEFT JOIN 以及从上述查询生成的派生表。

Demo here

【讨论】:

  • Giorgos,谢谢你这么好的回答!唯一的问题是它不显示 0 即windows 表上没有连接记录的房屋。有没有一种简单的方法可以在不做计数表的情况下添加它?
  • 顺便说一句,感谢您向我介绍 sqlfiddle!我以前使用过 jsfiddle,但不知道有一个用于 SQL 的。不错!
  • @DanSharp 房子有窗户的最大数量吗?
  • 不。我想我可以查询以找到最大值,然后将其用作固定最大值,但一般来说,给定房屋的连接记录数没有限制
  • @DanSharp 如果您想为结果中的每个“空白”输出一行,那么恐怕您必须使用计数表。看看here 如何在 MySQL 中构建和使用这样的表。在 SQL Server 中,您可以改用递归 CTE。
【解决方案2】:

您将需要添加“GROUP BY”子句。 检查这个问题out.

【讨论】:

    【解决方案3】:

    关键是使用having子句:

    select count(*) 
    from(select house from TableName
         group by house
         having count(*) = 1) t
    

    1 替换为您感兴趣的任何号码。

    【讨论】:

      【解决方案4】:

      以下应该可以满足您的需求:

      SELECT NUM_WINDOWS AS "# Windows", COUNT(*) AS "# Houses"
        FROM (SELECT HOUSE_ID, COUNT(*) AS NUM_WINDOWS
                FROM WINDOW
                GROUP BY HOUSE_ID)
        GROUP BY NUM_WINDOWS
      

      祝你好运。

      【讨论】:

      • 鲍勃,非常感谢!但是,这不包括我需要的带有 0 个窗户的房屋。有没有办法整合它?
      【解决方案5】:

      好吧,根据你所说的应该这样做:

      子查询获取房屋列表以及每个房屋的数量。下一个倒数,房子有多少窗户。

      Select Window_ct, COUNT(house_id) House_Ct
      From (select h.House_id, COUNT(w.Windows_Id) Window_Ct
              from Houses h
                  inner join Windowz w
                  On H.House_id = W.House.id
              Group by h.House_id) t
      Group by Window_Ct
      Order by 2
      

      【讨论】:

        猜你喜欢
        • 2014-05-07
        • 1970-01-01
        • 1970-01-01
        • 2020-03-03
        • 2018-02-03
        • 1970-01-01
        • 2012-10-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多