【问题标题】:SQL Server 2014 equivalent to mysql's find_in_set()SQL Server 2014 相当于 mysql 的 find_in_set()
【发布时间】:2024-01-19 12:47:02
【问题描述】:

我正在使用具有位置表的数据库,例如:

locationID | locationHierarchy
1          | 0
2          | 1
3          | 1,2
4          | 1
5          | 1,4
6          | 1,4,5

这样一棵树

1
--2
----3
--4
----5
------6

其中 locationHierarchy 是其所有祖先的 locationID 的 csv 字符串(想想层次结构树)。这样可以在给定起始 locationID 的情况下,在向树的顶部工作时轻松确定层次结构。

现在我需要编写代码以从祖先开始并递归查找所有后代。 MySQL 有一个名为“find_in_set”的函数,它可以轻松解析 csv 字符串以查找值。这很好,因为我可以说“在集合中查找值 4”,这将给出所有 locationID 为 4 的后代的位置(包括 4 本身)。

不幸的是,这是在 SQL Server 2014 上开发的,它没有这样的功能。 CSV 字符串是可变长度的(实际上允许无限级别),我需要一种方法来查找某个位置的所有祖先。

我在 Internet 上找到的很多将 find_in_set 函数模拟到 SQL Server 中的内容都假设了一个固定的层次结构深度,例如最多 4 级),这对我不起作用。

有没有人有存储过程或任何我可以集成到查询中的东西?我真的不想从这个表中提取所有记录来使用代码来单独解析 CSV 字符串。

我想在 locationHierarchy 字符串中搜索 locationID% 或 %,{locationid},% 会起作用,但速度很慢。

【问题讨论】:

  • 你能举例说明想要的结果吗?
  • 如果可能的话,我建议改变你的数据结构。有几个存储分层数据的示例。如果这不是一个选项,那么您的最后一条评论可能是使用like 的最简单的解决方案...
  • SQL Server 对这种数据结构有一个特殊的数据类型:hierarchyid,这可能是比“CSV 列”更好的选择:msdn.microsoft.com/en-us/library/bb677173%28v=sql.110%29.aspx
  • 虽然 SQL Server 确实有专门用于此的数据类型,但雇主希望不惜一切代价避免供应商锁定。我将不得不研究更好的层次结构,但与此同时,看起来需要一系列 LIKE 语句。

标签: sql sql-server csv find-in-set


【解决方案1】:

我想你想要like——在任一数据库中。像这样的:

select l.*
from locations l
where l.locationHierarchy like @LocationHierarchy + ',%';

如果您想要包含原始位置,那么一种方法是:

select l.*
from locations l
where l.locationHierarchy + ',' like @LocationHierarchy + ',%';

我还应该指出,SQL Server 对递归查询有适当的支持,因此除了层次结构树之外,它还有其他层次结构选项(这仍然是一个非常合理的解决方案)。

【讨论】:

    【解决方案2】:

    终于对我有用了..

    SELECT * FROM locations WHERE locationHierarchy like CONCAT(@param,',%%')    OR
                                        o.unitnumber like CONCAT('%%,',@param,',%%') OR
                                        o.unitnumber like CONCAT('%%,',@param)
    

    【讨论】:

      最近更新 更多