【问题标题】:select result in order of maximum match in a string sql按字符串sql中最大匹配的顺序选择结果
【发布时间】:2016-08-20 00:19:16
【问题描述】:

我在表 tblCountry 中有一个字符串列国家,例如“印度、澳大利亚、美国、英国”。 现在无论提供什么序列,例如“美国、德国、英国、印度、俄罗斯”,我都必须拆分 以空间为基础的字符串,然后显示列国家值中甚至存在单个国家的所有结果。 到目前为止,我通过以下查询实现了这一点。现在困难的部分是我必须首先显示结果 具有最大匹配列值。

例如,如果下面是列值:

'India, Austrailia, US, Italy'
'India, Malaysia, Austrailia, US, UK'
'UK, Austrailia, France, Korea, India'
'China, India, US, UK'

输入字符串是“澳大利亚、英国、印度、韩国、德国”,那么结果应该是最大匹配,如下所示: 输出是最匹配的国家,相关性如下所示

 'UK, Austrailia, France, Korea, India'   
 'India, Malaysia, Austrailia, US, UK'   
 'India, Austrailia, US, Italy'  
 'China, India, US, Brazil'


declare @matchCount int = 0;

SET @matchCount = (SELECT count(Item)  
        FROM dbo.SplitCountry('Austrailia, UK, India, Korea, Germany' , ',') 
        where Countries like '%'+Item+'%')

SELECT Countries, CASE 
WHEN @matchCount >0 THEN @matchCount 
     ELSE 0
  FROM tblCountry

我使用了一个函数来拆分字符串“SplitCountry”。我也不能在这里使用全文

【问题讨论】:

  • 什么是最大匹配?目前尚不清楚您想要实现什么。你能提供想要的输出吗?
  • 期望的输出在这里 'UK, Austrailia, France, Korea, India' 'India, Malaysia, Austrailia, US, UK' 'India, Austrailia, US, Italy' 'China, India, US,巴西的
  • 我还在上面的帖子中提到并编辑了输出

标签: sql sql-server sql-server-2008


【解决方案1】:

你必须

  • 创建临时表 #t1(CountriesID,Country)
  • 创建临时表 #t2(国家/地区)
  • 使用你的 split 函数填充 #t1,所以你有:

    CountriesID 国家

    1 印度

    1 澳大利亚

    1 个美国

    1 意大利

    2 印度

    2 马来西亚

    2 澳大利亚

    2 美国

    2 英国

    3 ...等等

  • 使用 split 函数填充 #t2,以便 t# 包含输入值

  • 终于:

SELECT #t1.CountriesID, c.Countries

来自 #t1

INNER JOIN #t2 on #t2.Country = #t1.Country

INNER JOIN tblCountry c ON c.CountriesID = #t1.CountriesID

按#t1.ID、c.Countries 分组

按计数排序(*) DESC

【讨论】:

  • 这是一个非常好的主意。但是每排国家都有大约50多个国家\城市。并且行数超过1000并且快速增加。这意味着 #t1 将包含 50*1000 行。性能好不好?我更多的是寻找使用 LIKE 或 CHARINDEX 关键字的东西。如果没有,那么这可能是唯一的选择。
  • 临时表可以处理数百万行,所以如果你在填充#t1之后在#t1上创建索引,性能应该还可以。最慢的部分是通过为#t1 中的每一行执行拆分函数来填充临时表,但无论如何都必须为任何选择的方法完成。
  • 我需要在整个原始表上运行一个循环来创建创建#t1 表吗?除了循环还有其他方法吗?
  • 循环应该不是问题——您只需要进行 1000 次迭代。但是,如果您不喜欢它,您可以使用一个选择查询创建一个巨大的 SQL 脚本并将其作为动态 sql “插入 #t1 (CountriesID, Country) exec (@sql)”运行,但这可能不安全( sql注入)。如果你选择最快的Split函数,那么你的查询会很快。
  • 感谢 Anton,但我现在拥有 1000 条记录,很快它将平均存储 50000 条记录。这意味着 temp #t1 中的 50 * 50000。我还担心临时表的存储位置,因为我的数据库限制仅为 200MB。这些临时表是否会像普通表一样存储,直到它们被删除或者大小不会影响任何东西?请指教
【解决方案2】:

最后,经过大量研究,我找到了一个简单的解决方案来解决我的问题。下面的查询非常适合我

声明@模式表 ( 模式 VARCHAR(20) );

INSERT INTO @patterns VALUES ('%india%'), ('%france%'), ('%US%'),('%UK%')

; 使用 CTEORD 作为 ( SELECT a.*,ROW_NUMBER() Over(Partition By country Order By p.pattern) AS RN FROM countries a 加入@patterns p ON(a.country LIKE p.pattern) )

选择 MAX(RN) 作为 RN,国家, 来自 CTEORD 组(按国家/地区) 按 RN desc 排序

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-02
    • 2018-01-09
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    相关资源
    最近更新 更多