参考以下正确回答的问题:
sql (oracle) counting number of overlapping intervals
在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 |
+----+------+-------+------+
我现在想找到重叠区间的数量(包括端点)[开始,停止] n_overlap
,以及所有stop
的{{1}}值的总和相同的id
,即:
name
我尝试了此解决方案,该方法有效:
+----+------+-------+------+-----------+------------+
| 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 |
+----+------+-------+------+-----------+------------+
但是,有没有一种方法可以压缩两个select / where查询,例如:
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;
这会引发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;
错误?
答案 0 :(得分:1)
您应该可以使用{this.props.categoryName}
和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
答案 1 :(得分:1)
这应该做到:
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
我可能会补充说,您的预期输出将考虑任何给定的行与自身重叠(请参阅第4行)。您可能要排除匹配的行。