我的表格如下:
ID DEFINITION VALUE
----------------------
1 A|B|C 1
2 A|All|All 3
3 A|B|All 6
4 All|B|All 4
该表背后的业务逻辑是,在传递字符串时应检索3个值的最具体的定义。 “全部”可以解释为'%'。
E.g。如果我的定义是'X | B | Z' - >价值应该是4。 如果我有'A | B | C' - >值应为1(不是1,3,6,4) - 只应从右侧开始检索最具体的结果。
'|'只是一个分隔符。每个子字符串可以是任何东西。我在这个例子中选择了A-C。不幸的是,它在一栏中连接起来。
我目前正在编写此查询,但遗憾的是它会导致所有匹配:`
SELECT *
FROM T1
INNER JOIN T2 ON T1.ID = T2.ID
AND (T2.DEFINITION = CASE
WHEN T2.DEFINITION = 'A|B|C'
THEN T2.DEFINITION
WHEN T2.DEFINITION = 'A|ALL|C'
THEN T2.DEFINITION
WHEN T2.DEFINITION = 'ALL|B|C'
THEN T2.DEFINITION
WHEN T2.DEFINITION = 'ALL|ALL|C'
THEN T2.DEFINITION
WHEN T2.DEFINITION = 'A|B|ALL'
THEN T2.DEFINITION....
ELSE 'All|All|All'
END)
我想检索case语句的第一个匹配而不是所有匹配。该案例陈述的顺序已经反映了我的业务逻辑。
有什么想法吗?
我担心解决方案非常简单但我现在看不到它。
答案 0 :(得分:2)
看起来你可以这样做:
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) desc;
如果您尝试对列中的值执行此操作,则可以使用apply
使用非常类似的方法。
答案 1 :(得分:1)
CREATE TABLE #TestTable
([ID] int, [DEFINITION] varchar(9), [VALUE] int)
;
INSERT INTO #TestTable
([ID], [DEFINITION], [VALUE])
VALUES
(1, 'A|B|C', 1),
(2, 'A|All|All', 3),
(3, 'A|B|All', 6),
(4, 'All|B|All', 4)
;
select [ID], [DEFINITION], [VALUE] from (
SELECT T1.*, row_number() over (order by CASE
WHEN T1.DEFINITION = 'A|B|C'
THEN 1
WHEN T1.DEFINITION = 'A|ALL|C'
THEN 2
WHEN T1.DEFINITION = 'ALL|B|C'
THEN 3
WHEN T1.DEFINITION = 'ALL|ALL|C'
THEN 4
WHEN T1.DEFINITION = 'A|B|ALL'
THEN 5
ELSE 6
END
) rnk
FROM #TestTable T1
)T where rnk = 1
结果:
ID DEFINITION VALUE
----------- ---------- -----------
1 A|B|C 1