首页新闻找找看学习计划

关于sql server 一个字段包含多个id的问题

0
悬赏园豆:5 [已解决问题] 解决于 2012-03-05 21:33

比如有俩表:表A和表B,
A表:
task_id,members
   1     34,35,36
   2     33,36
B表:
user_id  username
33          刘二
34          张三
35          李四
36          王五

我现在想通过sqlserver查询得到这样的结果

task_id  username
   1     张三,李四,王五
   2     刘二,王五

请问哪位大侠有高见?!!

masion237的主页 masion237 | 初学一级 | 园豆:7
提问于:2012-02-29 22:13
< >
分享
最佳答案
0

写个自定义函数,把memebers列传进去,就行了。

至于函数怎么写,可以自己搜一下。

收获园豆:3
Firen | 大侠五级 |园豆:5483 | 2012-03-01 09:16

多谢你的回答!

这个……,你说的函数是在sql中写的函数吗? 我在网上没怎么搜到,不知你是否可以给个相关函数的实例或者资料,多谢!

masion237 | 园豆:7 (初学一级) | 2012-03-04 19:32

CREATE FUNCTION [dbo].[GetUserName]
(@str nvarchar(max), --字符串
@spliter nvarchar(10)) --分割符
returns nvarchar(max)--返回构造好的username
AS
BEGIN
DECLARE @Result nvarchar(max)
DECLARE @UserName nvarchar(64)
DECLARE @Num int
DECLARE @Pos int
DECLARE @NextPos int

SET @Num = 0
SET @Pos = 1
SET @Result=''

 WHILE(@Pos <= LEN(@str))
 BEGIN
  SELECT @NextPos = CHARINDEX(@spliter, @str, @Pos)

  IF (@NextPos = 0 OR @NextPos IS NULL)
  SELECT @NextPos = LEN(@str) + 1

  SELECT @UserName=[username] FROM [dbo].[Table_B] WHERE [user_id]=RTRIM(LTRIM(SUBSTRING(@str, @Pos, @NextPos - @Pos)))

  SET @Result = @Result + @UserName +','
  SELECT @Pos = @NextPos+1
 END

RETURN @Result
END

--SELECT [task_id],[dbo].[GetUserName](members,',') FROM [dbo].[Table_A]

@masion237: 

Firen | 园豆:5483 (大侠五级) | 2012-03-05 08:57

@Firen: 十分感谢你的回答

真是学习了

masion237 | 园豆:7 (初学一级) | 2012-03-05 21:28

@masion237: 怎么写,这个好用不

Bj_junxia | 园豆:205 (菜鸟二级) | 2013-01-11 14:57
其他回答(6)
0

是不是可以考虑把表一改一下?改成这样的
task_id members

1 34

1 35

1 36

2 33

2 36 

你那个设置不好搞,如果数据不很多的话,可以考虑全部搞到内存里来,然后再拿程序做处理,SQL本身很难

收获园豆:1
丁学 | 园豆:18530 (专家六级) | 2012-03-01 11:54

谢谢你的回答

你说的没错,这个表这么设计是不太好。我以前在程序里处理的,因为慢,所以想着在sql中处理。

支持(0) 反对(0) masion237 | 园豆:7 (初学一级) | 2012-03-04 19:36

那样是特别的慢,每加载一行数据都要访问两次数据库,如何数据特别多的话,是很慢的。可不可以将要查询的所有数据的ID找出来,通过联合查询,得到所有数据对应的名称,将ID与名称保存的一个数组,然后在绑定数据的时候用ID直接去匹配这个数据获取名称,这样应该会快一些,第次只要访问两次数据库,就可以了,剩下的交给代码来处理就行了。。。

支持(0) 反对(0) KivenRo | 园豆:1722 (小虾三级) | 2012-03-04 20:52

@白雲天: 可以一次取出所有数据,然后在程序中能这两个表进行处理。比如:select * from A inner join B on A.user_id=B.user_id

如果一次只需要取一个任务的,可以直接在后面跟 where A.task_id=1

支持(0) 反对(0) 丁学 | 园豆:18530 (专家六级) | 2012-03-05 10:01
0

简单一点,在输出members的时候,通过字符串的ID返回username不就行了。。。

KivenRo | 园豆:1722 (小虾三级) | 2012-03-01 12:57

你是说在程序里写吗? 因为慢,所以想在sql中建立视图的方式实现我想要的结果

支持(0) 反对(0) masion237 | 园豆:7 (初学一级) | 2012-03-04 19:40
0

表结构和你需求太不合理了。

小材小用 | 园豆:639 (小虾三级) | 2012-03-02 14:27

多谢你的回答

表的结果是有些不合理。不过我感觉这个需求应该挺常见把,呵呵

支持(0) 反对(0) masion237 | 园豆:7 (初学一级) | 2012-03-04 19:41
0

你用linq连接数据库吗?

不是的话,把查出来的 1,2,3转换为Ilist<int>

 1        string str = "1,2,3,4";
2 var strlist = str.Split(',').ToList();
3 Dictionary<string, string> strdic = new Dictionary<string, string>();
4 strdic.Add("1", "刘二");
5 strdic.Add("2", "张三");
6 strdic.Add("3", "李四");
7 strdic.Add("4", "王五");
8
9 var namelist = from x in strdic where strlist.Contains(x.Key) select x;
10
11 foreach (var item in namelist)
12 {
13 Console.WriteLine(item.Value);
14 }
收获园豆:1
沈融兴 | 园豆:404 (菜鸟二级) | 2012-03-02 16:56

谢谢你的回答

你的方法不错,可是如果我有几十个id的话,是不是很耗内存?

其实我很倾向于1楼的通过在sql中写函数的方法实现,只是不太会写

支持(0) 反对(0) masion237 | 园豆:7 (初学一级) | 2012-03-04 19:46

@masion237: 我试过写存储过程...但是有点小问题...所以我现在就用这种方法...一定要考虑性能...我也没办法...暂时在这块没有性能问题...

支持(0) 反对(0) 沈融兴 | 园豆:404 (菜鸟二级) | 2012-03-04 22:10
0

建议更改一下表结构。

zhangdaowu5 | 园豆:265 (菜鸟二级) | 2012-03-02 17:12

谢谢你的回答

表确实建得不好,不过因为数据量大,所以现在只能先这样,不过因为想得到我的结果程序太慢,所以寻求建视图在sql中实现查询的方式

支持(0) 反对(0) masion237 | 园豆:7 (初学一级) | 2012-03-04 19:48
0

string [] arr=members.Spilt(',');   ???

Yellows | 园豆:45 (初学一级) | 2012-03-05 15:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册