[英]sql (oracle) count and sum within the same select/where query
With reference to the following and correctly answered question: 参考以下正确回答的问题:
sql (oracle) counting number of overlapping intervals sql(oracle)计算重叠间隔的数量
Given the following table test
in an oracle sql database: 在oracle sql数据库中进行下表
test
:
+----+------+-------+------+
| id | name | start | stop |
+----+------+-------+------+
| 1 | A | 1 | 5 |
+----+------+-------+------+
| 2 | A | 2 | 6 |
+----+------+-------+------+
| 3 | A | 5 | 8 |
+----+------+-------+------+
| 4 | A | 9 | 10 |
+----+------+-------+------+
| 5 | B | 3 | 6 |
+----+------+-------+------+
| 6 | B | 4 | 8 |
+----+------+-------+------+
| 7 | B | 1 | 2 |
+----+------+-------+------+
I would now like to find the number of overlapping intervals (endpoints included) [start, stop] n_overlap
as well as the sum of the stop
values for all id
having the same name
, ie: 我现在想查找重叠间隔(包括端点)的数目[start,stop]
n_overlap
以及所有具有相同name
id
的stop
值的总和,即:
+----+------+-------+------+-----------+------------+
| id | name | start | stop | n_overlap | sum_stops |
+----+------+-------+------+-----------+------------+
| 1 | A | 1 | 5 | 3 | 19 |
+----+------+-------+------+-----------+------------+
| 2 | A | 2 | 6 | 3 | 19 |
+----+------+-------+------+-----------+------------+
| 3 | A | 4 | 8 | 3 | 19 |
+----+------+-------+------+-----------+------------+
| 4 | A | 9 | 10 | 1 | 10 |
+----+------+-------+------+-----------+------------+
| 5 | B | 3 | 6 | 2 | 14 |
+----+------+-------+------+-----------+------------+
| 6 | B | 4 | 8 | 2 | 14 |
+----+------+-------+------+-----------+------------+
| 7 | B | 1 | 2 | 1 | 2 |
+----+------+-------+------+-----------+------------+
I tried this solution, which works: 我尝试了此解决方案,该方法有效:
select t.*,
(select count(*)
from test t2
where t2.name = t.name and
t2.start <= t.stop and
t2.stop >= t.start
) as n_overlap,
(select sum(stop)
from test t2
where t2.name = t.name and
t2.start <= t.stop and
t2.stop >= t.start
) as sum_stops
from test t;
But, is there a way to condense the two select/where queries, using eg: 但是,有没有一种方法可以压缩两个select / where查询,例如:
select t.*,
(select count(*) as n_overlap, sum(stop) as sum_stops
from test t2
where t2.name = t.name and
t2.start <= t.stop and
t2.stop >= t.start
)
from test t;
which raises a too many values
error? 这会引发
too many values
错误?
You should be able to do what you want with a JOIN
and GROUP BY
: 您应该可以使用
JOIN
和GROUP BY
来完成您想要的事情:
SELECT t.id, t.name, t.start, t.stop, COUNT(t2.name) AS n_overlap, SUM(t2.stop) AS sum_stops
FROM test t
LEFT JOIN test t2 ON t2.name = t.name AND t2.start <= t.stop AND t2.stop >= t.start
GROUP BY t.id, t.name, t.start, t.stop
Output: 输出:
id name start stop n_overlap sum_stops
1 A 1 5 3 19
2 A 2 6 3 19
3 A 5 8 3 19
4 A 9 10 1 10
5 B 3 6 2 14
6 B 4 8 2 14
7 B 1 2 1 2
This should do it: 应该这样做:
SELECT test.*, n_overlap, sum_stops
FROM test
LEFT JOIN (
SELECT m.id, COUNT(o.id) AS n_overlap, SUM(o.stop) AS sum_stops
FROM test AS m
INNER JOIN test AS o ON
/* m.id <> o.id AND */
m.name = o.name AND
m.stop >= o.start AND
o.stop >= m.start
GROUP BY m.id
) AS sq ON test.id = sq.id
I might add that your expected output considers any given row overlapping with itself (see row #4). 我可能会补充说,您的预期输出将考虑任何给定的行与自身重叠(请参阅第4行)。 You might want to exclude the row matching itself.
您可能要排除匹配自身的行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.