错在哪儿啦?为什么会都出现在COUNT(0) =2或3时的查询结果里?

RICHEER COCA 2021-05-06 10:12:36
引用sql代码

USE TEST
GO

if object_id('tempdb.dbo.#tb1') is not null drop table #tb1
go
create table #tb1 (Rid [int] IDENTITY(1,1) NOT NULL,SRN INT,no1 int,no2 int,no3 int,no4 int,no5 int,notext varchar(20))
insert #tb1
select '258131','09','22','31','33','34','09 22 31 33 34' union all
select '258132','09','22','31','33','35','09 22 31 33 35' union all
select '258133','09','22','31','34','35','09 22 31 34 35' union all
select '258134','09','22','32','33','34','09 22 32 33 34' union all
select '258135','09','22','32','33','35','09 22 32 33 35' union all
select '258136','09','22','32','34','35','09 22 32 34 35' union all
select '258137','09','22','33','34','35','09 22 33 34 35' union all
select '258138','09','23','24','25','26','09 23 24 25 26' union all
select '258139','06','23','24','25','27','06 23 24 25 27' union all
select '258140','09','23','24','25','28','09 23 24 25 28'


if object_id('tempdb.dbo.#tb2') is not null drop table #tb2 --数据量超大就用了临时表#tb2,没有用cte建临时表.
go

select *,ROW_NUMBER() over(PARTITION by rid order by val desc) as sn
into #tb2
from #tb1
unpivot(val for col in (no1,no2,no3,no4,no5)) p

if object_id('tempdb.dbo.#tb3') is not null drop table #tb3
go

select Rid,col,val%10 as val
,ROW_NUMBER() over(partition by rid order by val%10) as vid
into #tb3
from #tb2

select * from (
select Rid
from #tb3
group by Rid,val-vid having(COUNT(0) between 2 and 2 ) -- 后期需要所以不要用 having(COUNT(0)>n 的格式。
) a
left join #tb1 b on a.Rid=b.Rid


having(COUNT(0) between 2 and 2) ,是否可以理解为:提取no1,no2,no3,no4,no5个位上的数,有2个连续的自然数
查询结果为
引用
Rid Rid SRN no1 no2 no3 no4 no5 notext
3 3 258133 9 22 31 34 35 09 22 31 34 35
3 3 258133 9 22 31 34 35 09 22 31 34 35
5 5 258135 9 22 32 33 35 09 22 32 33 35
5 5 258135 9 22 32 33 35 09 22 32 33 35
10 10 258140 9 23 24 25 28 09 23 24 25 28


having(COUNT(0) between 3 and 3) ,是否可以理解为:提取no1,no2,no3,no4,no5个位上的数,有3个连续的自然数
查询结果为
引用
Rid Rid SRN no1 no2 no3 no4 no5 notext
2 2 258132 9 22 31 33 35 09 22 31 33 35
4 4 258134 9 22 32 33 34 09 22 32 33 34
6 6 258136 9 22 32 34 35 09 22 32 34 35
10 10 258140 9 23 24 25 28 09 23 24 25 28


having(COUNT(0) between 4 and 4) ,是否可以理解为:提取no1,no2,no3,no4,no5个位上的数,有4个连续的自然数
查询结果为
引用
Rid Rid SRN no1 no2 no3 no4 no5 notext
1 1 258131 9 22 31 33 34 09 22 31 33 34
7 7 258137 9 22 33 34 35 09 22 33 34 35
8 8 258138 9 23 24 25 26 09 23 24 25 26


having(COUNT(0) between 5 and 5) ,是否可以理解为:提取no1,no2,no3,no4,no5个位上的数,有5个连续的自然数
查询结果为
引用
Rid Rid SRN no1 no2 no3 no4 no5 notext
9 9 258139 6 23 24 25 27 06 23 24 25 27

问题描述:
1/为什么当COUNT(0) =2或3 不同时,查询结果里有相同的记录09 23 24 25 28 ?
2/查询的记录09 23 24 25 28的个位是3-4-5连续3个的自然数,而不是2个连续的自然数,为什么当COUNT(0) =2时会查询出这样的记录?
3/既然查询的记录09 23 24 25 28的个位是3-4-5连续3个的自然数,而不是2个连续的自然数,为什么会出现在COUNT(0) =2或3时的查询结果里,错在哪儿?
...全文
727 点赞 收藏 21
写回复
21 条回复
RICHEER COCA 05月08日
引用 19 楼 donwmufromdying 的回复:
我个人感觉是count用的不对。看看阿里的代码规范中应该也提及过oracle和mysql的不同。所以实际上应该尽量避免用count(0)而是用count(*)。
感谢,涨知识了
回复 点赞
kevinvolvo 05月07日
路过,挣个积分帮顶!!!!
回复 点赞
donwmufromdying 05月07日
我个人感觉是count用的不对。看看阿里的代码规范中应该也提及过oracle和mysql的不同。所以实际上应该尽量避免用count(0)而是用count(*)。
回复 点赞
RICHEER COCA 05月07日
所有大神
回复 点赞
唐诗三百首 05月06日
不好意思, 没看明白你的需求: 从表#tb1里找出个位上的数字不是连续的自然数记作#tb(one),那么#tb(one)的补集就是需要得到的结果。
回复 点赞
如果要找个位连续的次数能不能像下面这样

select * from (
SELECT X.Rid FROM (
	select Rid,COUNT(0) counts
	from #tb3
	group by Rid,val-vid 
	--having(COUNT(0) =2 )  
	-- 后期需要所以不要用 having(COUNT(0)>n 的格式。
	) X GROUP BY X.Rid HAVING MAX(X.counts)=2
) a
left join #tb1 b on a.Rid=b.Rid
回复 点赞
RICHEER COCA 05月06日
感谢
引用 2 楼 锟斤拷锟斤拷 的回复:
按照你的说法也许应该取max()=2
这里应该是把所有可能出现的连续次数都算进去了,那么count(0)=1的查询结果就会出错, 在#1楼的截图里,第一行 和 第二行 数据,counts=1的记录就不是需要查询的结果 简单地说,从表#tb1里找出个位上的数字不是连续的自然数记作#tb(one),那么#tb(one)的补集就是需要得到的结果。但不知道代码如何写
回复 点赞
按照你的说法也许应该取max()=2
回复 点赞
看一下count就知道了 这里应该是把所有可能出现的连续次数都算进去了,比如你说的那个,23 24 25的个位数345是counts=3,但是9 29的个位数89就是counts=2了
回复 点赞
RINK_1 05月06日
像#11说的那样,把余数去重后再排序获取序号试试,类似下面的。 如果不去重,是会有问题的,比如'258136','09','22','32','34','35','09 22 32 34 35'这条数据,不去重,会统计为3个连续自然数的

	select Rid,val%10 as val 
		,ROW_NUMBER() over(partition by rid order by val%10) as vid
into #tb3
	from #tb2
	group by Rid,val%10
回复 点赞
RICHEER COCA 05月06日
提示'to_number' 不是可以识别的 内置函数名称。有修改的办法吗
-- 构建数据表

if object_id('tempdb.dbo.#test1') is not null drop table #test1
go 
create table #test1 (Rid [int] IDENTITY(1,1) NOT NULL,Notext varchar(20),SNO int)
insert #test1
SELECT '01 02 03 07 16 32','1' UNION ALL
SELECT '01 02 03 07 16 32','2' UNION ALL
SELECT '01 02 03 07 16 32','3' UNION ALL
SELECT '01 02 03 07 16 32','7' UNION ALL
SELECT '01 02 03 07 16 32','6' UNION ALL
SELECT '01 02 03 07 16 32','2' UNION ALL
SELECT '01 03 04 06 12 16','1' UNION ALL
SELECT '01 03 04 06 12 16','3' UNION ALL
SELECT '01 03 04 06 12 16','4' UNION ALL
SELECT '01 03 04 06 12 16','6' UNION ALL
SELECT '01 03 04 06 12 16','2' UNION ALL
SELECT '01 03 04 06 12 16','6' 

--  用SQL查询连续数字并且统计连续个数
SELECT b.Notext, MIN (b.SNO) Start_HM, MAX (b.SNO) End_HM, count(*) as ccount
FROM (
      SELECT a.Notext,a.SNO, to_number (a.SNO - ROWNUM) cc  --'to_number' 不是可以识别的 内置函数名称。
      FROM (
            SELECT *
            FROM #test1
            ORDER BY Notext, SNO
           ) a 
     ) b
GROUP BY b.Notext, b.cc
having count(*) > 1
回复 点赞
RICHEER COCA 05月06日
引用 14 楼 锟斤拷锟斤拷 的回复:
[quote=引用 12 楼 RICHEER COCA 的回复:][quote=引用 9 楼 锟斤拷锟斤拷 的回复:]不对,看了一下count(0)好像也不是连续的次数啊。。这得从count(0)那里就改了]原来的思路应该没有问题,问题在于根本没实现原来的思路。直接把1 2 2 3判定为两个连续次数为2,而不是一个连续次数为3了
增加函数 如何?
回复 点赞
引用 12 楼 RICHEER COCA 的回复:
[quote=引用 9 楼 锟斤拷锟斤拷 的回复:]不对,看了一下count(0)好像也不是连续的次数啊。。这得从count(0)那里就改了
纠正count(0)无果啊,所以就想用#10的思路二[/quote]原来的思路应该没有问题,问题在于根本没实现原来的思路。直接把1 2 2 3判定为两个连续次数为2,而不是一个连续次数为3了
回复 点赞
RICHEER COCA 05月06日
引用 7 楼 锟斤拷锟斤拷 的回复:
这是你要的结果吗
用下面的这个语句验证一下就可以看到count(0)结果不对
select  notext from  #tb1 ---简称 大集合A
except
select notext  from #tb4 ---简称 大集合B
回复 点赞
RICHEER COCA 05月06日
引用 9 楼 锟斤拷锟斤拷 的回复:
不对,看了一下count(0)好像也不是连续的次数啊。。这得从count(0)那里就改了
纠正count(0)无果啊,所以就想用#10的思路二
回复 点赞
发现问题了,问题在于你把 1 2 2 3判定成不连续! 把tb3的代码改掉可能好点

if object_id('tempdb.dbo.#tb3') is not null drop table #tb3
go 

	select Rid,min(col) col,val%10 as val 
		,ROW_NUMBER() over(partition by rid order by val%10) as vid
	
into #tb3
	from #tb2 group by Rid,val%10
回复 点赞
RICHEER COCA 05月06日
纠正个别错误 问题描述:如何按查询要求找到连续数集合B 已知条件:大集合A 包含 连续数集合B 和 非连续数集合#tb(one) 查询要求:提取 no1, no2, no3, no4, no5, no6个位数是连续2个 或 2个以上的自然数为连续数集合B 设计思路: 思路一 按查询要求找到连续数集合B(但目前 代码出现问题) 思路二:曲线救国,现在查询连续数集合B的代码出现问题,就改变一下解题思路,去求非连续数集合#tb(one), 如果查询到了非连续数集合#tb(one),那么非连续数集合#tb(one)的补集就是连续数集合B,这样的话, 也可以解决问题(问题:按查询要求找到连续数集合B)
回复 点赞
不对,看了一下count(0)好像也不是连续的次数啊。。这得从count(0)那里就改了
回复 点赞
RICHEER COCA 05月06日
引用 5 楼 唐诗三百首 的回复:
不好意思, 没看明白你的需求: 从表#tb1里找出个位上的数字不是连续的自然数记作#tb(one),那么#tb(one)的补集就是需要得到的结果。
已知条件:大集合A 包含 连续数集合B 和 非连续数集合#tb(one),问题:按要求找到连续数集合B 查询要求:提取 no1, no2, no3, no4, no5, no6个位数是连续2个和2个以上的自然数为连续数集合B 设计思路:现在查询连续数集合B的代码出现问题,就改变以下思路,去求非连续数集合C,如果查询到了非连续数集合#tb(one),那么非连续数集合#tb(one)的补集就是连续数集合B,这样的话,也可以解决问题(问题:按要求找到连续数集合B)
回复 点赞
这是你要的结果吗
回复 点赞
发动态
发帖子
疑难问题
创建于2007-09-28

9306

社区成员

12.1w+

社区内容

MS-SQL Server 疑难问题
社区公告
暂无公告