我有一个包含两列ID
和Count
的表格,如下所示:
ID Count
1 1
2 1
3 2
4 3
5 1
6 2
7 1
8 1
9 1
10 2
我需要如下结果:
ID EndID
1 1
2 4
5 6
7 7
8 8
9 10
结果背后的逻辑是:StartID
在下一个EndID
之前计数为1且Id
为Count = 1
行。此处ID
1以1开始和结束,ID
2在ID
4之前开始和结束Count 1
。同样地,它继续下去。
答案 0 :(得分:3)
我们不知道你使用RDBMS
,所以这是标准版本:
SELECT id, COALESCE((SELECT MAX(ID) FROM tableName
WHERE id < (SELECT MIN(id) FROM tableName t2
WHERE t2.id > t1.id AND t2.c = 1 )),
(SELECT MAX(id) FROM tableName)) AS endid
FROM tableName t1 WHERE c = 1
没有COALESCE
,它看起来像:
SELECT id, (SELECT MAX(ID) FROM tableName
WHERE id < (SELECT MIN(id) FROM tableName t2 WHERE t2.id > t1.id AND t2.c = 1 ))
FROM tableName t1 WHERE c = 1
并导致:
1 1
2 4
5 6
7 7
8 8
9 NULL
这就是你需要最后COALESCE
部分的原因。我们的想法是选择比外部查询ID
更大的最小ID
,然后在此基础上找到小于ID
的最大ID
。所以即使id中包含空隙,你也可以使用它。
答案 1 :(得分:3)
不要对列名使用关键字。我在以下查询中使用cnt
代替count
。您必须构建您可以找到开始和结束值的组。如果ID是连续的,没有间隙,则使用:
select min(id) as startid, max(id) as endid
from
(
select id, cnt, id - cnt as groupkey
from mytable
) grouped
group by groupkey
order by min(id);
否则使用:
select min(id) as startid, max(id) as endid
from
(
select id, cnt, row_number() over (order by id) - cnt as groupkey
from mytable
) grouped
group by groupkey
order by min(id);
(假设您的DBMS当然具有ROW_NUMBER功能.ROW_NUMBER是标准SQL,因此很多DBMS都有它。)
答案 2 :(得分:1)
对于您问题中的数据,这有效:
select t.id,
(select min(t2.id) - 1
from t t2
where t2.id > t.id and t2.count = 1
) as EndId
from t
where t.count = 1;
这确实假设ids中没有间隙。