我的表T1看起来像这样:
ID VALUE ---------- 1 1 2 32 3 6 4 42 5 8 6 62 7 43 8 34
我的第二个T2看起来像这样:
ID DEFINITION --------------- 1 A|B|C 2 er|All|All|B 3 All|All|All 4 All|bela|All 5 All|All|All|G 6 A|All|All 7 All|B|All 8 Av|All|All|G
该表后面的业务逻辑是,传递字符串时,应应用最具体的DEFINITION,并应检索各自的值。“全部”可以解释为“%”。“ |” 只是一个分隔符,它定义了您实际传递的值。每个字符串都可以是任何东西…
例如,如果我的定义为’X | B | Z’->值应为7。如果我具有’A | B | C’->值应为1(不是1,6,7)-仅应该从右边的休假水平开始检索最具体的结果。
我已经问过一个非常类似的问题(SQL Server:获得第一个联接值),并获得了这个出色的解决方案Gordon Linnof,但不幸的是它涵盖的范围不止3个维度。我现在在该表中有新的值,该值可以有更多的子字符串。
有什么方法可以动态地获取正确的值?
select top (1) t.* from t where @str like replace(t.definition, 'All', '%') order by (case when t.definition like '%All%All%All%' then 3 when t.definition like '%All%All%' then 2 when t.definition like '%All%' then 1 else 0 end) asc;
编辑:我需要为这个问题添加更多细节,因为Habo添加了一些有效的注释:字符串值表示字母数字ID的egT34或ABC78,可以是varchar(255)。
您拥有的所有值越少,则它越具体-这是一个正确的选择。
这应该可以解决问题:
Declare @str VARCHAR(100) = 'A|B|C'; DECLARE @Test TABLE ( Id INT ,Definition VARCHAR(100) ) INSERT INTO @Test (Id, Definition) VALUES (1, 'A|B|C') ,(2, 'er|All|All|B') ,(3, 'All|All|All') ,(4, 'All|bela|All') ,(5, 'All|All|All|G') ,(6, 'A|All|All') ,(7, 'All|B|All') ,(8, 'Av|All|All|G') ; --------------------------------------------------------------------------- WITH Tester AS ( SELECT Id ,Definition ,(LEN(Definition) - LEN(REPLACE(Definition, 'All', ''))) / LEN('All') AS numAlls ,REPLACE(Definition, 'All', '%') AS Mask FROM @Test ) SELECT TOP 1 Id ,Definition FROM Tester WHERE @str LIKE Mask ORDER BY numAlls
这里的主键是列:
(LEN(Definition) - LEN(REPLACE(Definition, 'All', ''))) / LEN('All') AS numAlls
基本上,我接受您给出的顺序的想法,并通过简单地计算单词All在定义中出现的次数而不是显式创建多个语句来使其变得更通用。
All
希望有道理/能解决问题!
编辑:
为了完整起见并解决@HABO在评论中提出的真正有效的观点,即上述解决方案在单词All出现在字符串中的任何时间都将匹配,即使它是另一个语句/单词的一部分,下面的解决方案也是健壮/保证仅匹配以下情况All:
WITH Tester AS ( SELECT Id ,Definition ,(LEN('|' + Definition + '|') - LEN(REPLACE('|' + Definition + '|', '|All|', ''))) / LEN('|All|') AS numAlls ,REPLACE('|' + Definition + '|', '|All|', '|%|') AS Mask FROM @Test ) SELECT TOP 1 Id ,Definition FROM Tester WHERE '|' + @str + '|' LIKE Mask ORDER BY numAlls
基本上,您可以Definition使用分隔符(|)将其括起来,以确保Definition开头和结尾的每个部分都以分隔符(开始/结束值并非如此),然后我们就可以进行全文搜索|All|。
Definition
|
|All|
希望这对为什么这是一个更加健壮的解决方案有意义。