关于LIKE搜索的快速提问。如果我有一个值为'Analyst,Trainer'的列和另一列'Workflow,Analyst,Tester,Trainer',我想检查第一列中的值是否在第二列中。我们可以很容易地看出答案是肯定的,但它们不是有序的,所以我们不能做一个比较。
任何想法如何解决这个问题?可能会编写一个传递两个值的函数,并在两个函数上执行拆分例程?似乎可能有一种更简单的方法。
感谢您的耳朵。
大卫
答案 0 :(得分:1)
虽然这可能更适合编写脚本,但尝试使用SQL很有意思。
首先,您需要一个行标识符 - 这使用ROW_NUMBER()
。接下来,您可以查看使用CROSS APPLY
拆分逗号分隔列表。然后,您可以相应地比较列表。
这是一个有效的例子:
WITH YOURTABLE_WITH_RN AS (
SELECT ROW_NUMBER() OVER (ORDER BY col1) rn,
col1,
col2
FROM YourTable
),
YOURTABLE_COL1 AS (
SELECT rn,
Split.a.value('.', 'VARCHAR(100)') AS col1
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY col1) rn,
CAST ('<M>' + REPLACE(col1, ',', '</M><M>') + '</M>' AS XML) AS col1
FROM YourTable
) AS A
CROSS APPLY col1.nodes ('/M') AS Split(a)
),
YOURTABLE_COL2 AS (
SELECT rn,
Split.a.value('.', 'VARCHAR(100)') AS col2
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY col1) rn,
CAST ('<M>' + REPLACE(col2, ',', '</M><M>') + '</M>' AS XML) AS col2
FROM YourTable
) AS A
CROSS APPLY col2.nodes ('/M') AS Split(a)
)
SELECT T.rn,
T.col1,
T.col2,
CASE WHEN T2.rn IS NULL THEN 'Y' ELSE 'N' END AllIncluded
FROM YOURTABLE_WITH_RN T
LEFT JOIN (
SELECT T.rn
FROM YOURTABLE_COL1 T
LEFT JOIN YOURTABLE_COL2 T2 ON T.rn = T2.rn AND T.col1 = T2.col2
WHERE T2.rn IS NULL
) T2 ON T.rn = T2.rn
如果您的表中已有唯一标识符,则不需要第一个CTE(公用表表达式)或使用ROW_NUMBER()
。
答案 1 :(得分:0)
是的,我确实以这种方式冒险,然后在处理庞大的数据集时考虑了性能。我实际上前一段时间做了一些国际象棋编程,并认为可能会将这些值转换为'Analyst,Tester,Trainer',将ya转换为相应表中的位值,这样您在此处看到的值可能是7(1,2,4)然后也许'分析师,培训师'可能是5(1,4)所以如果我想测试'分析员,培训师'是否在'分析员,测试员,培训师'中我可以测试(7&amp; 5)= 5。好像它会起作用。这就是我们如何测试棋子是否在攻击广场上的方法。不知道为什么我之前没有发生这种情况。感谢您的评论。
答案 2 :(得分:0)
您可以使用XQuery方法(节点,值)拆分包含“Analyst,Trainer”值的列,然后使用LIKE运算符与“Workflow,Analyst,Tester,Trainer”值进行比较。
SELECT t.col1, t.col2, MIN(CASE WHEN t.col2 LIKE '%' + o.col1 + '%'
THEN 1 ELSE 0 END) AS IsMatch
FROM YourTable t
CROSS APPLY
(
SELECT Split.a.value('.', 'nvarchar(100)')
FROM (
SELECT CAST('<M>'+REPLACE(t.col1,',','</M><M>')+'</M>' AS xml) AS col1
) AS a
CROSS APPLY col1.nodes('/M') AS Split(a)
) o(col1)
GROUP BY t.col1, t.col2
SQLFiddle上的演示
您还可以使用带动态管理功能的选项sys.dm_fts_parser 在脚本执行之前,您需要检查是否已安装全文组件:
SELECT FULLTEXTSERVICEPROPERTY ('IsFulltextInstalled')
0 =未安装全文。 1 =已安装全文。 NULL =输入无效或错误。
如果0 =未安装全文,则此帖子对您How to install fulltext on sql server 2008?
是必要的SELECT t.col1, t.col2, MIN(CASE WHEN t.col2 LIKE '%' + o.col1 + '%'
THEN 1 ELSE 0 END) AS IsMatch
FROM YourTable t
CROSS APPLY (
SELECT display_term
FROM sys.dm_fts_parser('"'+ 'nn,' + t.col1 + '"', 1033, NULL, 0)
WHERE display_term NOT LIKE 'nn%'
) o(col1)
GROUP BY t.col1, t.col2
为避免排序操作,请使用index:
CREATE INDEX x ON YourTable(col1, col2)
仅供参考,最佳性能将来自sys.dm_fts_parser