基于字符串值的TSQL查找记录

时间:2016-12-20 22:34:47

标签: xml tsql parsing stored-procedures sql-server-2012

我正在使用员工数据库,其中一个字段是层次结构,显示他们向其报告的经理ID,他们的指示报告等。

此专栏的结构如下:

123|456|789|135|246|790

员工经理将是790,他们的经理246等,一直到链。

我正在尝试找到一种方法来搜索X Manager在员工层级中的记录。

例如:SELECT FROM employees WHERE '135' IN HierachyColumn

我无法使用XML,因为这是在链接服务器上,该服务器不允许在分布式查询中使用xml。我这样说是因为我会用XML包装每个值,然后使用.exist检查它的存在。

包含此字符串的自身数据在VIEW范围内,因此我可以根据建议略微操作它,但我在一个好的方法上画了一个空白。

是否还有其他基于此字符串进行搜索的选项?

3 个答案:

答案 0 :(得分:2)

假设(在一天结束时)您的查询将是不可搜索的。

在这种情况下,我倾向于选择CharIndex(),这实际上可能会提升效果http://cc.davelozinski.com/sql/like-vs-substring-vs-leftright-vs-charindex

Declare @Find varchar(25)='|451|'   -- Note I pre-piped the Find

Select * 
 From  employees
 Where CharIndex(@Find,'|'+HierarchyColumn+'|')>0

完全披露:前段时间,我进行了一系列测试。我的结果没有文章中列出的那么引人注目,但它们引人注目。

答案 1 :(得分:0)

这应该可以解决问题:

-- sample data
DECLARE @employees TABLE(HierarchyColumn varchar(100))
INSERT @employees 
VALUES ('123|456|789|135|246|790'), ('144|451|689|822'), ('144|451|689|822|990|999');

-- your search string
DECLARE @searchString int = 451;

-- solution
SELECT * 
FROM @employees 
WHERE HierarchyColumn LIKE CONCAT('%|',@searchstring,'|%')
OR HierarchyColumn LIKE CONCAT(@searchstring,'|%')
OR HierarchyColumn LIKE CONCAT('%|',@searchstring);

结果:

HierarchyColumn
---------------------------
144|451|689|822
144|451|689|822|990|999

或者,您可以这样做,这将得到相同的结果:

-- sample data
DECLARE @employees TABLE(HierarchyColumn varchar(100))
INSERT @employees 
VALUES ('123|456|789|135|246|790'), ('144|451|689|822'), ('144|451|689|822|990|999');

-- your search string
DECLARE @searchString int = 451;

-- solution
SELECT HierarchyColumn 
FROM @employees 
CROSS JOIN 
(
  VALUES (CONCAT('%|',@searchstring,'|%')),
         (CONCAT(@searchstring,'|%')),
         (CONCAT('%|',@searchstring))
) p(pattern)
WHERE HierarchyColumn LIKE pattern;

答案 2 :(得分:0)

如果所有层次结构节点长度相同,则另一种方法是将我的解决方案修改为this post,如下所示:

-- sample data
DECLARE @employees TABLE(HierarchyColumn varchar(100))
INSERT @employees 
VALUES ('123|456|789|135|246|790'), ('144|451|689|822'), ('144|451|689|822|990|999');

-- your search string
DECLARE @searchString int = 451;

SELECT * 
FROM
(
  SELECT 
    HierarchyColumn,
    itemLevel = ROW_NUMBER() OVER (PARTITION BY e.HierarchyColumn ORDER BY N), 
    item      = SUBSTRING(e.HierarchyColumn, ((N*4)-3), 3)
  FROM @employees e
  CROSS APPLY
  (
    SELECT TOP ((LEN(e.HierarchyColumn)/4)+1) ROW_NUMBER() OVER (ORDER BY (SELECT 1)) 
    FROM
    (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) a(x),
    (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) b(x),
    (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) c(x),
    (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) d(x)
  ) iTally(N)
) x
WHERE item = @searchString;

这不仅会返回节点,还会返回层次结构中节点的位置级别。

HierarchyColumn           itemLevel item
------------------------- --------- ----
144|451|689|822           2         451
144|451|689|822|990|999   2         451