在没有 FROM 子查询的 JOIN 中写入具有总和限制的 SQL 计数
Posted
技术标签:
【中文标题】在没有 FROM 子查询的 JOIN 中写入具有总和限制的 SQL 计数【英文标题】:Write SQL count with HAVING sum restrictions in a JOIN without a sub-query in FROM 【发布时间】:2018-04-20 19:44:51 【问题描述】:假设有两个表
* ----------------- 1
site_visits sites
site_id | visits site_id
1 | 15 1
1 | 10 2
2 | 20 3
2 | 45
3 | 55
目的是统计有多少网站,有超过 50 次访问。 DBMS 是带有 InnoDB 的 mysql。需要注意的是,必须有一个连接,因为两个表的列上都有 where 子句(在大图中)。
我已经设法用 FROM 中的子查询编写了这个;从上面的数据来看,它应该产生值 2,因为有 2 个这样的站点,id 2 和 3 的总和为 65 和 55,而 id 1 的总和仅为 25。
select count(*)
from (
select sum(visit.visits) as visits_sum
from sites site
join site_visits visit
on site.site_id = visit.site_id
group by site.site_id) as sub_sum
where visits_sum < 50
但是,我希望在 FROM 中没有子查询,以便能够将其与 ORM 一起使用;到目前为止,我管理的是:
select count(site.site_id)
from sites site
join site_visits visit
on site.site_id = visit.site_id
group by site.site_id
having sum(visit.visits) < 50
如果没有 group by,它将整个连接表求和并产生 3。使用它,它返回与总数一样多的条目,在本例中为 2。这些条目的值是 2 和 1(因为有连接表中有 2 个 id 为 2 的条目和 1 个 id 为 3 的条目)。 count(count(...))
之类的东西可能会这样做,但这是不允许的。
【问题讨论】:
您使用的是哪个 DBMS? @RadimBača DBMS 是 MySQL;我也会编辑这个问题。 什么版本的 MySQL?你在 8.0.2 以上吗? 哪个数据库? mysql还是sql? @reds MySQL 或 SQL :D 【参考方案1】:这个怎么样:
select count(1) from
(select a.site_id,sum(visits) as visits_sum from site_visits a,sites b where
a.site_id = b.site_id group by a.site_id having sum(visits)>50) as ab
【讨论】:
在标题和问题描述中都写到需要解决方案,而 FROM 中没有子查询(由于 ORM 限制); FROM 中带有子查询的解决方案已发布在问题详细信息中。 还有另一种方法可以避免子查询@m3th0dman,在函数中执行。【参考方案2】:好的,如果您使用的是 MySQL 8.0.2 及更高版本,那么您可以使用窗口函数。我省略了site
表,因为对于示例来说它不是必需的。
select distinct count(count(site_visits.site_id)) over ()
from site_visits
group by site_visits.site_id
having sum(site_visits.visits) > 50
demo
【讨论】:
@reds 真的是为什么? Hibernate/JPA 不支持分析函数...因此,如果不使用原始查询,OP 将无法将其集成到他的代码库中。 @reds MySQL 的更高版本可能支持这一点,但 OP 对子查询的厌恶可能是由于 JPA,使用分析函数使这个问题变得更加困难。 @RadimBača 但我认为它没有抓住重点,因为您的查询不能直接映射到 JPA ...它必须是原始查询,因此整个代码库将依赖于MySQL 8. @m3th0dman 很好,那么我猜 MySQL 中没有满足您要求的解决方案。【参考方案3】:select count(site_id) from (
select site_id from site_visit group by site_id having sum(visits)>50)t
【讨论】:
可以消除连接,因为根据定义未出现在site_visits
中的站点没有访问+1。
我在问题(和标题)中提到我不能在 FROM 中使用子查询,因为 ORM 不支持它。我在 FROM 中找到了一个带有子查询的工作解决方案。
@m3th0dman JPA 支持子查询,这是我心中的正确答案。
@m3th0dman 连接中的子查询像派生表一样可以接受吗?
select count(distinct st.site_id) from site_visit st inner join (select site_id from site_visit group by site_id sum(visits)>50) t on st.site_id=t.site_id以上是关于在没有 FROM 子查询的 JOIN 中写入具有总和限制的 SQL 计数的主要内容,如果未能解决你的问题,请参考以下文章