【问题标题】:Efficient SQL Bucket Sort based on Length of Substring Match基于子串匹配长度的高效 SQL 桶排序
【发布时间】:2013-11-28 22:42:15
【问题描述】:

给定一个包含按字母顺序索引的字符串的 SQL 数据库表,我如何执行按子字符串匹配排序的搜索查询?

例如,给定数据集:

bad
banana
bandana
banker
bed
brother

而搜索字符串band,我希望结果排序如下

bandana (index 0-3 matched)
banana  (index 0-2 matched)
banker
bad     (index 0-1 matched)
bed     (index 0 matched)
brother

请注意,我们只关心匹配的子字符串的长度。落入每个桶的匹配不必按字母顺序排序,我只关心它们落入的桶

所以我天真地猜测问题涉及:

  1. 查看与我的每行输入匹配的子字符串长度
  2. 根据匹配长度将每一行放入适当的桶中
  3. 按降序排列存储桶,即(匹配 4 个字符,匹配 3 个字符,2..)

但这听起来很昂贵,那么我怎样才能在 SQL 或 C# 中实现它并高效地完成呢?

我可以从这里受益的类似问题/模式吗?

非常感谢

【问题讨论】:

  • 你能分享一下你使用什么算法来执行实际的字符串匹配吗?
  • 我愿意接受建议,因为现阶段我仍在脑海中制定代码。它必须是具有理想复杂性的东西,其中运行时间优先于使用的内存

标签: c# sql bucket-sort


【解决方案1】:

不确定这是否是最有效的方法。

使用数字表,将字符串拆分为字符并将其连接到搜索字符串的拆分中,然后按计数和字符串排序。

DECLARE @t TABLE ( string VARCHAR(50) )

INSERT INTO @t (string)
VALUES 
    ('bad'),
    ('banana'),
    ('bandana'),
    ('banker'),
    ('bed'),
    ('brother')

DECLARE @search VARCHAR(50) = 'band'

;WITH numbers AS
(
    SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY t1.number) AS n
    FROM master..spt_values t1 
    CROSS JOIN master..spt_values t2
)   
SELECT string
FROM @t t
CROSS APPLY (
    SELECT SUBSTRING(t.string, numbers.n, 1) c, n
    FROM numbers
    WHERE numbers.n <= LEN(string)
) s1
JOIN (
    SELECT SUBSTRING(@search, numbers.n, 1) c, n
    FROM numbers
    WHERE numbers.n <= LEN(@search)
) s2 ON s2.c = s1.c
    AND s2.n = s1.n 
GROUP BY string
ORDER BY COUNT(1) DESC, string

demo

【讨论】:

  • 非常感谢!诚然,有些结构超出了我的 SQL 知识范围!我假设限制结果集我可以更改 10000?另外,相对于输入长度和表格大小,该解决方案的复杂性是多少?
  • 数字表当然可以限制为TOP (LEN(@search))。我认为复杂性(忽略数字表生成,只生成一个直到搜索字符串长度的序列)大致类似于O(n*m)+O(n+m)+O(2n),但我对计算复杂性不是很了解,并且有很多考虑因素,例如索引等
【解决方案2】:

字符串操作和 sql-server 不是最匹配的 afaik。

我最好的办法是尝试修改版本的 Bayer-Moore-horspool 来查找匹配字符的数量。但是,在错过时,您不会跳过完整的字长,只会跳过最大匹配的长度。然后简单地插入相应的桶中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-19
    • 2011-09-09
    • 1970-01-01
    • 2013-05-22
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    相关资源
    最近更新 更多