写了一上午还没有较好的办法,请大家帮忙了。
Table1表的数据如下:
ID1 ID2
A00001 B00002
A00001 B00003
A00002 B00004
A00002 B00005
A00003 B00005
A00003 B00006
A00003 B00007
......
说明:Table1表的关健字是:ID1+ID2,主要是想得出下面的TYPE这个字段的值,
希望查询出的结果:
ID1 ID2 TYPE
A00001 B00002 1
A00001 B00003 1
A00002 B00004 2
A00002 B00005 2
A00003 B00005 2
A00003 B00006 2
A00003 B00007 2
.....请帮写条语句,求出这个TYPE的值。感谢。
Table1表的数据如下:
ID1 ID2
A00001 B00002
A00001 B00003
A00002 B00004
A00002 B00005
A00003 B00005
A00003 B00006
A00003 B00007
......
说明:Table1表的关健字是:ID1+ID2,主要是想得出下面的TYPE这个字段的值,
希望查询出的结果:
ID1 ID2 TYPE
A00001 B00002 1
A00001 B00003 1
A00002 B00004 2
A00002 B00005 2
A00003 B00005 2
A00003 B00006 2
A00003 B00007 2
.....请帮写条语句,求出这个TYPE的值。感谢。
解决方案 »
- 这样的存储过程怎么测试
- 同样的表,同样的nvarchar字段上的索引,同样的sql语句,sql2000/2005执行结果却不同,帮忙看下
- .sls是什么文件
- SQL SERVER2005差异备份
- 推荐一个网格式分布式数据库中间件给大家
- 高分求助关于自动日志恢复的解决方案
- 我COPY网上一段存储过程的代码,运行,怎么提示错误?
- 菜鸟的简单问题
- 连接SqlServer2000时有问题,请各位高人指点
- 请教:在VB中如何使用ADO添加、删除、修改MS SQL SERVER7.0中的Text和Image字段的内容?(小弟囊中羞涩,暂给40分)
- sql server 2000 service pack4安装出现问题
- table转换格式的问题 包含转换为xml格式的列
(2)A00002被B00004和B00005使用到,但B00005又使用了A00003,而A00003使用了B00006和B00007,依此类推....。所以它们是同一个组,给值2。
--SQL2000
Create table T1(ID1 varchar(10), ID2 varchar(10))
Insert into T1 select 'A00001', 'B00002'
Insert into T1 select 'A00001', 'B00003'
Insert into T1 select 'A00002' ,'B00004'
Insert into T1 select 'A00002' ,'B00005'
Insert into T1 select 'A00003' ,'B00005'
Insert into T1 select 'A00003' ,'B00006'
Insert into T1 select 'A00003' ,'B00007'
GOselect * ,type =0 into #T from T1declare @type int , @id1 varchar(10), @id2 varchar(10)
set @type=0
Update #T
set @type= case when id1=@id1 or id2=@id2
then @type
else @type+1 end,
@id1=id1,@id2=id2,
type=@typeselect * from #T
/*
A00001 B00002 1
A00001 B00003 1
A00002 B00004 2
A00002 B00005 2
A00003 B00005 2
A00003 B00006 2
A00003 B00007 2*/
Drop table T1,#T
--> 测试数据:[tb]
if object_id('[tb]') is not null drop table [tb]
create table [tb]([ID1] varchar(6),[ID2] varchar(6))
go
insert [tb]
select 'A00001','B00002' union all
select 'A00001','B00003' union all
select 'A00002','B00004' union all
select 'A00002','B00005' union all
select 'A00003','B00005' union all
select 'A00003','B00006' union all
select 'A00003','B00007'
select h.[ID1],h.[ID2],f.type
from [tb] h join
(
select [ID1],max(type) as type
from
(
select t.*,
case (select count(1) from [tb] where ID1 <> t.ID1 and [ID2] = t.[ID2]) when 0 then 1 else 2 end as type
from [tb] t
) r
group by [ID1]) f
on h.[ID1] = f.[ID1]
----------------------------------
A00001 B00002 1
A00001 B00003 1
A00002 B00004 2
A00002 B00005 2
A00003 B00005 2
A00003 B00006 2
A00003 B00007 2
--SQL2000
Create table T1(ID1 varchar(10), ID2 varchar(10))
Insert into T1 select 'A00001', 'B00002'
Insert into T1 select 'A00001', 'B00003'
Insert into T1 select 'A00002' ,'B00004'
Insert into T1 select 'A00002' ,'B00005'
Insert into T1 select 'A00003' ,'B00005'
Insert into T1 select 'A00003' ,'B00006'
Insert into T1 select 'A00003' ,'B00007'Insert into T1 select 'A00008' ,'B00008'
GOselect id=identity(int,1,1),ID2
INTO #ID
from T1
group by ID2
select ID1,T1.ID2, type=id
INTO #T
from T1,#ID
where T1.ID2=#ID.ID2declare @type int, @i int
set @i=1
declare c1 cursor for select id from #ID order by id
open c1
fetch next from c1 into @type
while @@fetch_status=0
begin
if exists(select top 1 1 from #T where type=@type)
begin
Update #T
set type=@i
where exists (select top 1 1 from #T A
where A.type=#T.type
and exists(select top 1 1 from #T B
where B.ID1=A.ID1
and B.type=@type)
)
end if exists(select top 1 1 from #T where type!=@i
and ID1 in (select ID1 from #T where type=@i))
begin
select @type=max(type)
from #T
where ID1 in (select ID1 from #T where type=@i)
end else
begin
set @i=@i+1
fetch next from c1 into @type
end
end
close c1
deallocate c1Update #T
set type= (select count(distinct type) from #T A where A.type<=#T.type)select * from #T
/*
ID1 ID2 type
------------------------------------
A00001 B00002 1
A00001 B00003 1
A00002 B00004 2
A00002 B00005 2
A00003 B00005 2
A00003 B00006 2
A00003 B00007 2
A00008 B00008 3*/
Drop table T1,#T,#ID
DECLARE @TB TABLE([KFID] VARCHAR(6), [KFNO] VARCHAR(11))
INSERT @TB
SELECT 'A00001', 'B00002' UNION ALL
SELECT 'A00001', 'B00003' UNION ALL
SELECT 'A00002', 'B00004' UNION ALL
SELECT 'A00002', 'B00005' UNION ALL
SELECT 'A00003', 'B00005' UNION ALL
SELECT 'A00003', 'B00006' UNION ALL
SELECT 'A00003', 'B00007'
CREATE TABLE #([KFID] VARCHAR(6), [KFID2] VARCHAR(6), [KFNO2] VARCHAR(11), GRP INT, ID INT IDENTITY(1,1))
INSERT #
SELECT T.KFID, T2.KFID AS KFID2, T2.KFNO AS KFNO2, 0 AS GRP
FROM @TB AS T LEFT JOIN @TB AS T2
ON T.KFID<>T2.KFID AND T.KFNO=T2.KFNO
ORDER BY T.KFID,CASE WHEN T2.KFID IS NULL THEN 1 ELSE 0 END,T2.KFID
--SELECT * FROM #CREATE CLUSTERED INDEX IX_KFID ON #(KFID)
CREATE INDEX IX_KFID2 ON #(KFID2)
CREATE INDEX IX_KFNO2 ON #(KFNO2)
CREATE UNIQUE INDEX IX_ID ON #(ID)DECLARE @GRP INT, @ID INT, @KFID VARCHAR(6), @KFID2 VARCHAR(6),@KFNO2 VARCHAR(11), @ROWCNT INT, @MAXGRP INT
SET @GRP=1
SET @MAXGRP=1
SET @ID=1SELECT @KFID=KFID FROM # WHERE ID=@ID
UPDATE # SET GRP=@GRP WHERE KFID=@KFID
SET @ROWCNT=@@ROWCOUNTWHILE @ROWCNT>0
BEGIN
SET @ID=@ID+@ROWCNT
SELECT TOP 1 @MAXGRP=CASE WHEN T2.GRP IS NULL THEN @MAXGRP+1 ELSE @MAXGRP END,
@GRP=ISNULL(T2.GRP, @MAXGRP),
@KFID=T.KFID
FROM # AS T LEFT JOIN # AS T2
ON (T.KFID2=T2.KFID2 OR T.KFNO2=T2.KFNO2) AND T2.KFID<T.KFID
WHERE T.ID=@ID
ORDER BY T2.KFID
UPDATE # SET GRP=@GRP WHERE KFID=@KFID AND GRP=0
SET @ROWCNT=@@ROWCOUNT
END
SELECT KFID,GRP FROM #DROP TABLE #
if object_id('[tb]') is not null drop table [tb]
create table [tb]([ID1] varchar(6),[ID2] varchar(6))
go
insert [tb]
select 'A00001','B00002' union all
select 'A00001','B00003' union all
select 'A00002','B00004' union all
select 'A00002','B00005' union all
select 'A00003','B00005' union all
select 'A00003','B00006' union all
select 'A00003','B00007' union all
select 'A00004','B00008' union all
select 'A00004','B00009'
select *,type = 0 into #temp from [tb]declare @i int,@id varchar(6)select @i = 1declare cursor_temp cursor for
select distinct [ID1] from [tb]
open cursor_temp
fetch next from Cursor_temp into @id
while @@fetch_status = 0
begin
if exists(select 1 from [tb] where [ID2] in (select [ID2] from [tb]
where [ID1] = @id) and [ID1] <> @id)
begin
update #temp set type = @i where [ID1] = @id
end
else
begin
update #temp set type = (select max(type)+1 from #temp) where [ID1] = @id
select @i = @i + 1
end
fetch next from Cursor_temp into @id
end
close Cursor_temp
deallocate Cursor_tempselect * from #tempdrop table #temp
----------------------------------------
A00001 B00002 1
A00001 B00003 1
A00002 B00004 2
A00002 B00005 2
A00003 B00005 2
A00003 B00006 2
A00003 B00007 2
A00004 B00008 3
A00004 B00009 3
回答一下playwarcraft朋友的问题,ID1和ID2是会相互交叉的,它们是ID值,其实都是从00000001开始的。稍后若OK再谢谢大家。
谢谢各位,我倾向于nianran520的答案,自认为简洁点(不知道是不是先入为主,呵),我原来是不想用游标,所以来发贴。
playwarcraft的代码在8000条数据真实环境中要跑9分28秒,我在他的基础上做了优化,现在只需要9秒钟。下面是代码,和大家分享。 create table #temp (ID1 varchar(20),ID2 varchar(20))
insert into #temp
select 'A00001','B00002' union all
select 'A00001','B00003' union all
select 'A00002','B00004' union all
select 'A00002','B00005' union all
select 'A00003','B00005' union all
select 'A00003','B00006' union all
select 'A00003','B00007' union all
select 'A00004','B00008' union all
select 'A00004','B00009' union all
select 'A00005','B00010' ---union all
//modify 1
CREATE CLUSTERED INDEX C_Idx_temp ON #temp(ID1) select id=identity(int,1,1),ID2
INTO #ID
from #temp
group by ID2 select A.ID1,B.ID2, B.id As type
INTO #T
from #temp A
inner join #ID B
On A.ID2=B.ID2 //modify 2
CREATE CLUSTERED INDEX C_Idx_t ON #T(ID1)
create index type_idx on #t (type) declare @type int, @i int
set @i=1
declare c1 cursor for select id from #ID order by id
open c1
fetch next from c1 into @type
while @@fetch_status=0
begin
if exists(select top 1 1 from #T where type=@type)
begin
Update #T
set type=@i
where exists (select top 1 1 from #T A where A.type=#T.type
and exists( select top 1 1 from #T B
where B.ID1=A.ID1
and B.type=@type))
end if exists(select top 1 1 from #T where type!=@i
and ID1 in (select ID1 from #T where type=@i))
begin
select @type=max(type)
from #T
where ID1 in (select ID1 from #T where type=@i)
end
else
begin
set @i=@i+1
fetch next from c1 into @type
end
end
close c1
deallocate c1
//modify 3
update a
set type=b.xh
from #t a
inner join (select type,row_number() over (order by type) as xh from #t
group by type) b
on a.type=b.type select * from #t
drop table #t
drop table #ID
drop table #t