我有两列的表,一个是int,另一个是varchar列
SeqId status
int varchar(50)
状态栏有10个状态,例如status1,status2,status3,... status10
我想写一个查询来查找SeqId的范围,其中status7,status8,status9 count(*)为零。
表数据,
SeqId Status
1 status1
2 status2
3 status3
4 status4
5 status5
6 status6
7 status7
8 status8
9 status9
10 status10
11 status1
12 status2
13 status3
14 status4
15 status5
16 status9
17 status2
18 status7
19 status3
20 status5
......
1000 status6
我的第一个期望输出
当我使用15到20之间的范围时,
不正确的查询现在不包含零,
Select status, count(*)
from table1
where seqId between 15 and 20
group by status
**Status Count**
status1 0
status2 1
status3 1
status4 0
status5 2
status6 0
status7 1
status8 0
status9 1
status10 0
接下来如果可能的话,我想找到一个范围,其中所有这3种状态,8,9和10都为零。
答案 0 :(得分:2)
您可以使用case
语句将其转换为布尔问题。所以:
select t.*, (case when status in ('status8', 'status9', 'status10') then 0 else 1 end) as flag
from t;
您现在想要找到最长的零序列。这是一个间隙和岛屿问题。一种解决方案是行号的差异以定义组:
select top 1 min(id), max(id), count(*) as length
from (select t.*,
(row_number() over (order by id) - row_number() over (partition by flag order by id)) as grp
from (select t.*, (case when status in ('status8', 'status9', 'status10') then 0 else 1 end) as flag
from t
) t
) t
where flag = 0
group by grp, flag
order by count(*) desc;
答案 1 :(得分:0)
假设您有一个状态表:
SELECT A.STATUS, COALESCE(B.COUNT, 0) AS COUNT FROM STATUS_TABLE A
LEFT JOIN (SELECT STATUS, COUNT(*) AS COUNT FROM TABLE1 GROUP BY STATUS) B
ON A.STATUS = B.STATUS
答案 2 :(得分:0)
Select base.status, count(statusVal.Status)
from table1 base
left join ( select distinct Status from table1
) statusVal
on statusVal.Status = base.status
where seqId between 15 and 20
group by base.status
全部为零
select SeqId from data
except
select SeqId from data where Status in ( ..... )
答案 3 :(得分:0)
对于您的第一个问题,通用的t-sql解决方案将是
create table #t (id int, [status] varchar(12))
go
insert into #t (id, status) values
(1 ,'status1')
, (2 ,'status2')
, (3 ,'status3')
, (4 ,'status4')
, (5 ,'status5')
, (6 ,'status6')
, (7 ,'status7')
, (8 ,'status8')
, (9 ,'status9')
, (10 ,'status10')
, (11 ,'status1')
, (12 ,'status2')
, (13 ,'status3')
, (14 ,'status4')
, (15 ,'status5')
, (16 ,'status9')
, (17 ,'status2')
, (18 ,'status7')
, (19 ,'status3')
, (20 ,'status5')
go
; WITH c (status, cnt) as
(
select distinct [status], cnt=0
from #t
)
, c2 as ( select t.[status], cnt=count(*)
from #t t
where t.id between 15 and 20
group by t.[Status])
select c.* from c2
right join c
on c.[status]=c2.[status]
where c2.status is null
union
select c2.* from c2;
对于你的第二个问题,@ Gordon Linoff提供了一个很好的解决方案,但我认为他的解决方案中存在一个错字。 where子句应该是
where flag = 1 -- instead of 0
答案 4 :(得分:0)
select convert(int,substring(a.[status],7,2)),a.*,isnull(b.CNT,0)
from
(select distinct [status] from #t) a
left join
(select [status],COUNT(*)as CNT from #t
where id between 15 and 20
Group by [status]) b
on a.status=b.status
order by 1