问一个SQL的问题:我有个表,里面有个字段 f_deptpath ,有个记录是这样的:
\\-1\21\2,\\-1\21\4, 我现在要根据一些特别的字符串来查找到这条记录,如果是 \\-1\21\2\5\6就可以查到这个记录,同一,\\-1\21\4\3\2也可以查到这个记录,\\-1\21\5\1就没有办法找到这条记录就是说,这个字段内容里面,如果有个字符串里面有这个字段内容里面以,分割的内容,就可以查到 说清楚一点就是:
 我有个表,是一个记录企业公告的表,因为企业公告要针对部门或职位的,所以,我在表里增加了两个字段,一个是接受公告的部门列表,一个是接受公告的职位列表,都是以“,”分割的,
比如, 管理部门的路径是“\\-1\2”,生产部门的路径是“\\-1\3”,那么,表示管理部门和生产部门是同一级的,如果我要发送公告给管理部门和生产部门,那么,字段部门列表的内容就是“\\-1\2,\\-1\3,”, 我所属的部门是仓库,部门路径是"\\-1\2\5\6",表示我是属于生产部门下的资材部门下的仓库,
因为以上的公告是发给生产部的,所以,作为生产部的下属子部门,我是可以接收这个公告的,怎么通过查询来完成这个动作。

解决方案 »

  1.   

    可以考虑使用 SELECT * FROM TableName WHERE 字段+'\' LIKE '%\部门编号\%'
      

  2.   

    DVD_01(OK_008):因为 我所处的部门的路径有可能大于字段里面的路径,也有可能小于字段里面的路径,小于的情况就可以不要考虑了,但是大于的情况就需要做分析,如下:公告部门列表字段内容“\\-1\2,\\-1\3,”,部门路径\\-1\2\5,\\-1\2\5\6都可以收到。 如果使用like,就是这样:SELECT * FROM TableName WHERE 字段+'\' LIKE '%\\-1\2\5\%' 这样就查询不到了
      

  3.   

    建分隔函数:
    CREATE FUNCTION f_splitSTR(
    @s   varchar(8000),   --待分拆的字符串
    @split varchar(10)     --数据分隔符
    )RETURNS @re TABLE(col varchar(100))
    AS
    BEGIN
    DECLARE @splitlen int
    SET @splitlen=LEN(@split+'a')-2
    WHILE CHARINDEX(@split,@s)>0
    BEGIN
    INSERT @re VALUES(LEFT(@s,CHARINDEX(@split,@s)-1))
    SET @s=STUFF(@s,1,CHARINDEX(@split,@s)+@splitlen,'')
    END
    INSERT @re VALUES(@s)
    RETURN
    END
    GO
    f_splitSTR('\\-1\21\2,\\-1\21\4,','\\-1\21\')
    按\\-1\21\分隔,f_deptpath 为2,4,
    f_splitSTR(f_splitSTR('\\-1\21\2\5\6','\\-1\21\'),'\')按\\-1\21\分隔\\-1\21\2\5\6为2\5\6再按\分隔为2 5 6
      

  4.   

    我要实现的功能如下:
     一个公告,发送给指定的部门,是多个部门,要求接收部门的子部门都可以接受到部门表:
      id 
      父部门
      部门名称公告表
      id
      接受部门  部门id+‘,’+部门id,以,分割用户表
      id
      部门id如何根据用户所处的部门来得到公告因为以上我没有办法实现,主要是在公告表接受部门的字段里面,记录的是部门id,没有记录子部门,所以需要在这里进行子部门分析,会很复杂和速度慢,所以,我更改了表的定义,如下:部门表:
      id 
      父部门
      部门名称
      部门路径  记录当前记录在整个部门树形的路径,如\\-1\2\3\5公告表
      id
      接受部门  部门路径+‘,’+部门路径,以,分割用户表
      id
      部门id所以,产生了这个问题
      

  5.   

    部门表:
      id 
      父部门
      部门名称公告表
      id
      接受部门  部门id+‘,’+部门id,以,分割用户表
      id
      部门id
    按照第1个表设计,是可以根据一个公告去查相应的部门的.
    参考方法:
    1.先提取上级部门:
    SELECT * FROM 部门表 WHERE 部门ID IN(公告表) ---这里使用动态SQL语句来完成,得到的结果可以先写入临时表.
    2.使用替归的方法找临时表里所有的下级部门.(最大层为32层)
      

  6.   

    DVD_01(OK_008):
     如果这样设计的话,会不会出现性能问题?如果有200个员工,每天有200个公告(邮件),这样查询会不会出现问题?SELECT * FROM 部门表 WHERE 部门ID IN(公告表)这句我不理解,我的接受部门是以,分隔的,怎么查?
      

  7.   

    我想到增加一个表来解决问题:
    公告表 //取消接收部门列表
      id
      内容..
    增加一个接收部门表
     id
     公告id
     接收部门 ID //能够接收的部门的id,就是找出所有能接收的部门,记录在这个表里面,虽然记录多,但是查询方便了
      

  8.   

    SELECT * FROM 部门表 WHERE 部门ID IN(公告表)这句我不理解,我的接受部门是以,分隔的,怎么查?如:
    DECLARE @Exec_Sql nvarchar(4000)
    SET @Exec_Sql='SELECT 部门ID FROM 部门表 '
    SELECT @Exec_Sql=@Exec_Sql+'WHERE 部门ID IN ('+[接受部门]+')' FROM 公告表 WHERE ...
    EXECUTE(@Exec_Sql)要是楼主能重新设计公告表结构,那是更好了,免了很多技术难题,这样最好不过。
      

  9.   

    DVD_01(OK_008):
    我的表还没有设计好呢,能给些建议吗?
      

  10.   

    我增加了一个表,变成了这样:
    公告表 //取消接收部门列表
      id
      内容..
    增加一个接收部门表
     id
     公告id
     接收部门列表  //能够接收的部门的id+“,”+id 就是找出所有能接收的部门,例如,如果要给公告增加一个接收部门,那么获取这个部门下所有部门,构成接收部门列表,加入到接收部门表里面,这样,如果增加一个部门就给接收部门表增加一条记录,比较方便,查询的时候,只要根据自己的部门id是否在 接收部门列表里面就可以了, 现在碰到一个新的问题: 如何知道用户查看过这个公告呢?如果另外新建一个查看表:
     id
     公告id
     用户id
    记录哪些公告被哪些用户查看过,如果用这个表联合上面的表查询,会什么都得不到,因为只有查看过才会记录到查看表里面。如何在用户登录的时候,能够得到当前用户可以看的公告且标志哪一个公告是否查阅过?
      

  11.   

    rocy520(一个人走~~)  ????? 是测试?