感觉挺有难度的一个SQL语句,请高手指点(邹建请进,在线等.......)

hsmserver 2004-10-14 08:23:23
第一个问题:
结构是这样的
姓名 票据单号
张三 01100
张三 01102
张三 01112
李四 04120

想要得到的结果为:
姓名 票据单号
张三 0100,01102,01112
李四 04120

第二个问题
表结构如下:
姓名 起始票号 截止票号
张三 01001 01005
张三 01006 01009
张三 01100 01102
张三 01103 01119
张三 01121 01126
李四 02000 02005

希望得到的结果如下
姓名 起始票号1 截止票号1 起始票号2 截止票号2 起始票号3 截止票号3 .....
张三 01001 01009 01100 01119 01121 01126
李四 02000 02005


感觉第一比较常见,但弄了半天没弄出来
第二个比较复杂,希望大家给予指点一二,谢谢!!!
...全文
153 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hsmserver 2004-10-14
  • 打赏
  • 举报
回复
多谢两位,看来我把简单问题复杂化了,不过还是底子比较薄一些
学了不少东西,保存留档
呵呵
WGYKING 2004-10-14
  • 打赏
  • 举报
回复
MARK
zjcxc 元老 2004-10-14
  • 打赏
  • 举报
回复
第二个问题同时涉及了编号连续和交叉表的处理,是一个综合问题而已.
hsmserver 2004-10-14
  • 打赏
  • 举报
回复
中海和邹建的方法是一样的,开拓者也有异曲同工之妙,我还是基础比较差,CASE 。。 WHEN 。。 THEN [用表达式] 都不知道,大家一说豁然开朗,多谢大家帮助!第二个问题确实比较复杂吧?
zjcxc 元老 2004-10-14
  • 打赏
  • 举报
回复
--第二个问题

--测试

--测试数据
create table tb(姓名 varchar(10),起始票号 varchar(10),截止票号 varchar(10))
insert tb select '张三','01001','01005'
union all select '张三','01006','01009'
union all select '张三','01100','01102'
union all select '张三','01103','01119'
union all select '张三','01121','01126'
union all select '李四','02000','02005'
go

--查询处理
select id=0,姓名,起始票号,截止票号=(
select min(截止票号) from tb aa
where 姓名=a.姓名 and 起始票号>=a.起始票号
and not exists(select * from tb where 姓名=aa.姓名 and 起始票号-1=aa.截止票号))
into #t from tb a
where not exists(
select * from tb where 姓名=a.姓名 and 截止票号+1=a.起始票号)
order by 姓名

declare @s varchar(8000),@i varchar(10)
update #t set @i=case 姓名 when @s then @i+1 else 1 end,id=@i,@s=姓名
select @s='',@i=max(id) from #t
while @i>0
select @s=',[起始票号'+@i+']=max(case id when '''
+@i+''' then 起始票号 else '''' end),[截止票号'
+@i+']=max(case id when '''
+@i+''' then 截止票号 else '''' end)'+@s
,@i=@i-1
exec('select 姓名'+@s+' from #t group by 姓名')
drop table #t
go

--删除测试
drop table tb

/*--测试结果

姓名 起始票号1 截止票号1 起始票号2 截止票号2 起始票号3 截止票号3
---------- ---------- ---------- ---------- ---------- ---------- ----------
李四 02000 02005
张三 01001 01009 01100 01119 01121 01126
--*/
victorycyz 2004-10-14
  • 打赏
  • 举报
回复
第二个问题,呵呵,我的方法比较笨拙一点。

create table T (n varchar(10),b varchar(5),e varchar(5))
insert t select '张三', '01001', '01005'
union select '张三', '01006', '01009'
union select '张三', '01100', '01102'
union select '张三', '01103', '01119'
union select '张三', '01121', '01126'
union select '李四', '02000', '02005'

create table #t(id int,n varchar(10),b varchar(5),e varchar(5))

insert #t (n,b)
select a.n,a.b
from t a left join t b on a.n=b.n and a.b=right('0000'+cast(cast(b.e as int)+1 as varchar(5)),5)
where b.n is null

update #t set id=(select count(*) from #t where n=a.n and b<=a.b) from #t a

insert #t (n,e)
select a.n,a.e
from t a left join t b on a.n=b.n and a.e=right('0000'+cast(cast(b.b as int)-1 as varchar(5)),5)
where b.n is null

update #t set id=(select count(*) from #t where n=a.n and e<=a.e) from #t a where b is null

declare @s varchar(8000)

set @s=''

select @s=@s + ' , max(case when id='+cast(id as varchar(10))+' then b else '''' end) as begin'+cast(id as varchar(10))
+ ' , max(case when id='+cast(id as varchar(10))+' then e else '''' end) as end' + cast(id as varchar(10))
from #t
group by id

set @s='select n '+@s + ' from #t group by n '

exec ( @s )

drop table t,#t
hsmserver 2004-10-14
  • 打赏
  • 举报
回复
三位的方法都有可行之处,我确实有点晕
不过自定义函数我以前没用过,刚看了一下,感觉处理一些问题确实比较不错

但关于第二个问题有什么好的解决方法吗?
用存储过程能实现吗?
最好不要用游标
zjcxc 元老 2004-10-14
  • 打赏
  • 举报
回复
--第一个问题,前面是用自定义函数的,我用临时表来解决,这样也适用于sql7.0

--测试数据
create table tb(姓名 varchar(10),票据单号 varchar(10))
insert tb select '张三','01100'
union all select '张三','01102'
union all select '张三','01112'
union all select '李四','04120'
go

--查询处理
select 姓名,票据单号=cast(票据单号 as varchar(8000)) into #t from tb order by 姓名
declare @姓名 varchar(10),@r varchar(8000)
update #t set @r=case 姓名 when @姓名 then @r+','+票据单号 else 票据单号 end
,票据单号=@r,@姓名=姓名
select 姓名,票据单号=max(票据单号) from #t group by 姓名
drop table #t
go

--删除测试
drop table tb

/*--测试结果

姓名 票据单号
---------- ----------------------
李四 04120
张三 01100,01102,01112

(所影响的行数为 2 行)
--*/
hsmserver 2004-10-14
  • 打赏
  • 举报
回复
回复人: liuxinbao2k(liuxinbao) ( ) 信誉:100 2004-10-14 20:37:00 得分: 0


楼上
请问用GROUP BY
不简单吗>


问题有那么简单,我还要问吗?
liuxinbao2k 2004-10-14
  • 打赏
  • 举报
回复
楼上
请问用GROUP BY
不简单吗>
Andy__Huang 2004-10-14
  • 打赏
  • 举报
回复
第一个问题:


create table tb(姓名 varchar(10), 票據單號 varchar(10))
Insert into tb
select '張三','01100'
union all select '張三','01102'
union all select '張三','01112'
union all select '李四','04120'

select * from tb

--函數
create function dbo.fn_bb(@a varchar(10))
returns varchar(1000)
as
begin
declare @s varchar(1000)
set @s=''
select @s=@s+[票據單號]+',' from tb where 姓名=@a
return (left(@s,len(@s)-1))
end

--刪除
drop table tb
drop function dbo.fn_bb

--結果
select 姓名,票據單號=dbo.fn_bb(姓名) from tb group by 姓名 order by 2
姓名 票據單號
--------------------------
張三 01100,01102,01112
李四 04120
victorycyz 2004-10-14
  • 打赏
  • 举报
回复
第一个问题的参考:
http://community.csdn.net/Expert/topic/3245/3245226.xml?temp=.4298059
liuxinbao2k 2004-10-14
  • 打赏
  • 举报
回复
第一个问题
用GROUP BY 姓名

34,873

社区成员

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

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