SQL Server:获取第一个连接值

时间:2018-06-14 00:51:51

标签: sql sql-server database tsql

我的表格如下:

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语句的第一个匹配而不是所有匹配。该案例陈述的顺序已经反映了我的业务逻辑。

有什么想法吗?

我担心解决方案非常简单但我现在看不到它。

2 个答案:

答案 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