假设我有一个名为Table
的表
+----+------+------+
| ID | Col1 | Col2 |
+----+------+------+
| 1 | A | 0 |
| 2 | B | 0 |
| 3 | C | 1 |
| 4 | A | 1 |
| 5 | D | 0 |
| 6 | A | 0 |
| 7 | F | 1 |
| 8 | H | 1 |
+----+------+------+
我想要这个结果:
+----+------+------+
| ID | Col1 | Col2 |
+----+------+------+
| 3 | C | 1 |
| 4 | A | 1 |
| 7 | F | 1 |
+----+------+------+
也就是说:
Col1
= A且Col2
= 1,则选择相应的行Col1
= A且Col2
= 0,则取其下的第一行,其中Col2
= 1 我尝试过类似的事情
SELECT CASE
WHEN t.Col2 > 0
THEN t.Col2
WHEN t1.Col2 > 0
THEN t1.Col2
WHEN t2.Col2 > 0
THEN t2.Col2
...
FROM Table t
JOIN table t1 ON t.id - 1 = t1.id
JOIN table t2 ON t.id - 2 = t2.id
...
WHERE t.Col2 = 'A'
但这不是我想要的。 我无法提出任何解决方案。我该怎么办?
答案 0 :(得分:2)
嗯。 。 。我在想lag()
:
select t.*
from (select t.*,
lag(col1) over (order by id) as prev_col1,
lag(col2) over (order by id) as pev_col2
from t
) t
where col1 = 'A' and col2 = 1 or
(pev_col1 = 'A' and prev_col2 = 0);
答案 1 :(得分:2)
这是一个查询,查找您要求的所有此类行,它们是Col1 = A和Col2 = 1,还是在Col1 = A和Col2 = 0之后的第一个Col2 = 1。
一个简短的解释是查询仅考虑Col2 = 1的行。如果Col1 = A当然需要行。但是如果回头查找Col2 = 1的最接近的前一行以及Col1 = A和Col2 = 0的最接近的前一行,它还会占用该行,并且发现前者比后者更靠后(或者前者没有)不存在。
create table MyTable (
ID int not null identity(1,1),
Col1 varchar(100) not null,
Col2 varchar(100) not null
);
insert MyTable (Col1, Col2) values ('A', '0');
insert MyTable (Col1, Col2) values ('B', '0');
insert MyTable (Col1, Col2) values ('C', '1');
insert MyTable (Col1, Col2) values ('A', '1');
insert MyTable (Col1, Col2) values ('D', '0');
insert MyTable (Col1, Col2) values ('A', '0');
insert MyTable (Col1, Col2) values ('F', '1');
insert MyTable (Col1, Col2) values ('H', '1');
select * from MyTable;
select *
from MyTable as t
where t.Col2 = 1
and (t.Col1 = 'A'
or isnull((select top (1) t2.ID
from MyTable as t2
where t2.ID < t.ID
and t2.Col2 = 1
order by t2.ID desc
), 0)
<
(select top (1) t2.ID
from MyTable as t2
where t2.ID < t.ID
and t2.Col1 = 'A'
and t2.Col2 = 0
order by t2.ID desc
)
)
order by t.ID;
答案 2 :(得分:2)
使用窗口函数SUM()和MIN():
with
cte1 as (
select *, sum(case when col1 = 'A' and col2 = 0 then 1 else 0 end) over (order by id) grp
from tablename
),
cte2 as (
select *, min(case when col2 = 1 then id end) over (partition by grp order by id) next_id
from cte1
)
select id, col1, col2
from cte2
where (col1 = 'A' and col2 = 1) or (id = next_id)
请参见demo。
结果:
> id | col1 | col2
> -: | :--- | ---:
> 3 | C | 1
> 4 | A | 1
> 7 | F | 1