使用条件在sql上查找最后一行

时间:2015-12-14 12:11:42

标签: sql

我有一个包含两列IDCount的表格,如下所示:

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且IdCount = 1行。此处ID 1以1开始和结束,ID 2在ID 4之前开始和结束Count 1。同样地,它继续下去。

3 个答案:

答案 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中没有间隙。