急切的征求SQL语句

nuaawyd 2009-04-27 10:02:43
表A(a1,a2,a3,a4)
示例1:要求取得两条记录(记录a和记录b)中(记录a.a2=记录b.a4 and 记录a.a4=记录b.a2)
a1 a2 a3 a4
1 名称1 100 名称2
2 名称3 10 名称4
3 名称2 20 名称1
得到结果:
a1 a2 a3 a4
1 名称1 100 名称2
3 名称2 20 名称1
示例2:要求取得两条记录(记录a、记录b和记录c)中(记录a.a4=记录b.a2 and 记录b.a4=记录c.a2 and 记录c.a4=记录a.a2)
a1 a2 a3 a4
1 名称1 100 名称2
2 名称3 10 名称4
3 名称2 20 名称5
4 名称6 20 名称7
5 名称5 300 名称1
得到结果:
a1 a2 a3 a4
1 名称1 100 名称2
3 名称2 20 名称5
5 名称5 300 名称1
以此类推

急切的征求SQL语句
...全文
324 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
tengjian1981 2009-04-29
  • 打赏
  • 举报
回复
你先给表中a2和a4建一下索引


create index index_tb_a2 on tb(a2)
create index index_tb_a4 on tb(a4)




然后在执行下面代码,这次主要是改进效率问题



create table #temp(a2 varchar(50))
create table #temp1(a2 varchar(50))
declare @temp_name varchar(50)
declare @temp_a2 varchar(50)
declare @temp_a4 varchar(50)
declare @flag bit
declare @result bit
declare mycursor cursor for select a2,a4
from [tb]
order by a2 asc
open mycursor

fetch next from mycursor
into @temp_a2,@temp_a4
while(@@fetch_status=0)
begin
set @flag=1
set @result=0
if(not exists(select * from #temp where a2=@temp_a2))
begin
truncate table #temp1
insert into #temp1 values(@temp_a2)
while(@flag=1)
begin
insert into #temp1 values(@temp_a4)
if(exists(select * from [tb] where [a2]=@temp_a4))
begin
select @temp_name=[a4] from [tb] where [a2]=@temp_a4
set @temp_a4=@temp_name
if(@temp_a4=@temp_a2)
begin
set @result=1
set @flag=0
end
end
else
begin
set @result=0
set @flag=0
end
end
if(@result=1)
insert into #temp select * from #temp1
end

fetch next from mycursor
into @temp_a2,@temp_a4
end
close mycursor
deallocate mycursor

select a.*
from [tb] a inner join #temp b on a.a2=b.a2

drop table #temp
drop table #temp1
GO




zoom8 2009-04-29
  • 打赏
  • 举报
回复
--------示例1:要求取得两条记录(记录a和记录b)中(记录a.a2=记录b.a4 and 记录a.a4=记录b.a2)
select c.* from a c,a b where c.a2 = b.a4 and c.a4 = b.a2--------示例2:要求取得两条记录(记录a、记录b和记录c)中(记录a.a4=记录b.a2 and 记录b.a4=记录c.a2 and 记录c.a4=记录a.a2)
select c.* from a c,a b,a d where c.a4 = b.a2 and b.a4 = d.a2 and d.a4 = c.a2 order by c.a1
-晴天 2009-04-28
  • 打赏
  • 举报
回复
create table [tb]([a1] int,[a2] varchar(10),[a3] int,[a4] varchar(10))
insert [tb] select 1,'名称1',100,'名称2'
union all select 2,'名称3',10,'名称4'
union all select 3,'名称2',20,'名称5'
union all select 4,'名称6',20,'名称7'
union all select 5,'名称5',300,'名称1'
union all select 6,'名称2',20,'名称1'
go
select a.* from tb a inner join tb b on a.a1<>b.a1 where a.a2=b.a4 and a.a4=b.a2
select a.* from tb a inner join tb b on a.a1<>b.a1 inner join tb c on c.a1<>b.a1
where c.a1<>a.a1 and a.a4=b.a2 and b.a4=c.a2 and c.a4=a.a2 order by a1
go
drop table tb
/*
a1 a2 a3 a4
----------- ---------- ----------- ----------
1 名称1 100 名称2
6 名称2 20 名称1

(2 行受影响)

a1 a2 a3 a4
----------- ---------- ----------- ----------
1 名称1 100 名称2
3 名称2 20 名称5
5 名称5 300 名称1

(3 行受影响)
*/
等不到来世 2009-04-28
  • 打赏
  • 举报
回复
--sql 2005的一种解法:
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([a1] int,[a2] varchar(5),[a3] int,[a4] varchar(5))
insert [tb]
select 1,'名称1',100,'名称2' union all
select 2,'名称3',10,'名称4' union all
select 3,'名称2',20,'名称5' union all
select 4,'名称6',20,'名称7' union all
select 5,'名称5',300,'名称1'
go
--select * from [tb]

declare @lvl int
set @lvl=3 --在此定义循环长度

;with szx as
(
select *,rootid=a1,lvl=1 from tb
union all
select b.*,a.rootid,a.lvl+1
from szx a join tb b on a.a4=b.a2
and a.a1<b.a1 and a.rootid<>b.a1
)
select a1,a2,a3,a4 from szx
where rootid in (select rootid from szx where lvl=@lvl)
/*
a1 a2 a3 a4
----------- ----- ----------- -----
1 名称1 100 名称2
3 名称2 20 名称5
5 名称5 300 名称1

(3 行受影响)
*/
tengjian1981 2009-04-28
  • 打赏
  • 举报
回复
上面代码多了几行冗余代码


if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([a1] int,[a2] varchar(10),[a3] int,[a4] varchar(10))
insert [tb] select 1,'名称1',100,'名称2'
union all select 2,'名称3',10,'名称4'
union all select 3,'名称2',20,'名称5'
union all select 4,'名称6',20,'名称7'
union all select 5,'名称5',300,'名称1'

union all select 6,'名称10',300,'名称11'
union all select 7,'名称11',300,'名称10'
union all select 8,'名称12',300,'名称13'
union all select 9,'名称14',300,'名称15'

union all select 10,'名称20',300,'名称21'
union all select 11,'名称22',300,'名称24'
union all select 12,'名称21',300,'名称26'
union all select 13,'名称26',300,'名称27'
union all select 14,'名称27',300,'名称28'
union all select 15,'名称28',300,'名称20'

union all select 16,'名称30',300,'名称30'




if object_id('fn_IsCyc') is not null drop function fn_IsCyc
go
create function fn_IsCyc
(
@name1 varchar(10),
@name2 varchar(10)
)
returns int
as
begin
declare @name varchar(10),@result int
set @result=0
if(@name1=@name2) set @result=1
else
begin
if(exists(select * from [tb] where [a2]=@name2))
begin
select @name=[a4] from [tb] where [a2]=@name2
select @result=dbo.fn_IsCyc(@name1,@name)
end
else
set @result=0
end
return @result
end


select * from [tb] where dbo.fn_IsCyc([a2],[a4])=1

guguda2008 2009-04-28
  • 打赏
  • 举报
回复
楼主能保证表中的数据都像例子里那么合法吗?还是有像36楼那样的情况?
liulongfei_123 2009-04-28
  • 打赏
  • 举报
回复
Proe4.0基础教程,幻灯片PPT,含全部prt文件。(1-8章)
怎么找不到呀
Proe4.0基础教程,幻灯片PPT,含全部prt文件。(9-11章)
就可以找到并且可以下载。
tengjian1981 2009-04-28
  • 打赏
  • 举报
回复
LZ应该是取出只要能形成闭环的数据吧
零壹世界 2009-04-28
  • 打赏
  • 举报
回复
楼主的题目有问题!!!!!
是不是只要列出满足要求的相关行呢?把不满足要求的行去掉,还是要求详细描述出哪几条是关联起来满足要求的。
给你个例子;

if object_id('t_a') is not null drop table t_a
GO
insert into t_a
select '名称1',40,'名称2' union all
select '名称2',50,'名称4' union all
select '名称3',60,'名称4' union all
select '名称4',70,'名称3' union all
select '名称5',80,'名称6' union all
select '名称5',90,'名称1' union all
select '名称7',100,'名称4' union all
select '名称5',20,'名称3' union all
select '名称2',10,'名称1' union all
select '名称6',110,'名称5' union all
select '名称4',110,'名称1'union all
select '名称4',110,'名称2'union all
select '名称3',110,'名称2'
GO

上面的情况,你的第一个要求出来的结果是什么?
第二个要求出来的结果又是什么?
别只弄出一点点数据的例子出来,这样很难让人明白的。。。。
tengjian1981 2009-04-28
  • 打赏
  • 举报
回复



if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([a1] int,[a2] varchar(10),[a3] int,[a4] varchar(10))
insert [tb] select 1,'名称1',100,'名称2'
union all select 2,'名称3',10,'名称4'
union all select 3,'名称2',20,'名称5'
union all select 4,'名称6',20,'名称7'
union all select 5,'名称5',300,'名称1'

union all select 6,'名称10',300,'名称11'
union all select 7,'名称11',300,'名称10'
union all select 8,'名称12',300,'名称13'
union all select 9,'名称14',300,'名称15'

union all select 10,'名称20',300,'名称21'
union all select 11,'名称22',300,'名称24'
union all select 12,'名称21',300,'名称26'
union all select 13,'名称26',300,'名称27'
union all select 14,'名称27',300,'名称28'
union all select 15,'名称28',300,'名称20'

union all select 16,'名称30',300,'名称30'




if object_id('fn_IsCyc') is not null drop function fn_IsCyc
go
create function fn_IsCyc
(
@name1 varchar(10),
@name2 varchar(10)
)
returns int
as
begin
declare @name varchar(10),@result int
set @result=0
if(@name1=@name2) set @result=1
else
begin
if(exists(select * from [tb] where [a2]=@name2 and [a4]=@name1))
set @result=1
else
begin
if(exists(select * from [tb] where [a2]=@name2))
begin
select @name=[a4] from [tb] where [a2]=@name2
select @result=dbo.fn_IsCyc(@name1,@name)
end
else
set @result=0
end
end
return @result
end


select * from [tb] where dbo.fn_IsCyc([a2],[a4])=1






如果是大数据量时,测试一下效率
nuaawyd 2009-04-28
  • 打赏
  • 举报
回复
怎么写啊?数据库不是太大,效率问题忽略不计
tengjian1981 2009-04-28
  • 打赏
  • 举报
回复
写个function是可以,function里用递归,但是效率问题就不敢保证了
nuaawyd 2009-04-28
  • 打赏
  • 举报
回复
如果是四连环是不是继续加条件啊?
sdhdy 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 nuaawyd 的回复:]
你现在只是我的例子程序

如果有四个循环怎么办?
[/Quote]
似乎只能这么写,动态的貌似不行。
nuaawyd 2009-04-28
  • 打赏
  • 举报
回复
能说的详细点嘛,这方面我很弱的,哈
llsen 2009-04-28
  • 打赏
  • 举报
回复
把表当做两个表来用就好了啊

select tableA.*  from A as tableA
inner join A as tableB on ...


后面都加你的条件就ok了
nuaawyd 2009-04-28
  • 打赏
  • 举报
回复
tengjian1981 :
我运行了3个小时还是没结果啊
usher_gml 2009-04-28
  • 打赏
  • 举报
回复
我也帮顶顶...
nuaawyd 2009-04-28
  • 打赏
  • 举报
回复
有解决办法嘛?
nuaawyd 2009-04-28
  • 打赏
  • 举报
回复
有解决办法嘛?
加载更多回复(33)

34,588

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧