sql - 返回在同一列或不同列中找到多个关键字的行,以显示这些关键字以及受尊重的列
问题描述
我希望有人根据以下示例表对以下内容提出快速建议:
|Column1 |Column2 |Column3 |Column4 |
|--------|--------|--------|--------|
|ABC XYZ |DFG KIL |YUI XYZ |ABC IOH |
|YDT NJK |ABC HJK |NJM XYZ |WEC OPP |
我正在考虑能够构建一个查询来搜索同一列或不同列中的多个单词,以显示这些关键字和受尊重的列。这一点,无需依靠光标。
即,如果用户搜索关键字,我想要以下输出'ABC', 'YUI', 'OPP'
:
|Col1 |Col2 |Col3 |Col4 |Found Keyword|Keyword Found in |
|--------|--------|--------|--------|-------------|-----------------|
|ABC XYZ |DFG KIL |YUI XYZ |ABC IOH |ABC, YUI |Col1,Col3,Col4 |
|YDT NJK |ABC HJK |NJM XYZ |WEC OPP |ABC, OPP |Col2,Col4 |
我一直在尝试做各种事情,例如(sys.columns, UNION ALL, CROSS JOIN)
,但到目前为止收效甚微。
有超过 100K 行,最好的方法是什么?
注意:我使用的是 SQL Server 2012 版本。
解决方案
已经有人评论说您的设计应该重新设计。
现在,这是一个应该响应您的用例的查询。这通过声明您在子查询中搜索的单词(这使得添加更多内容非常容易),然后JOIN
使用表来工作:基本上,检查所有连接的列是否与搜索的值匹配(假设空间分隔器)。
然后,外部查询使用STRING_AGG()
(在 SQL Server 2017 中可用)执行聚合作业。生成匹配列列表的部分有点棘手,因为需要为每条记录手动生成 CSV 值。
注意:如果您有一个唯一的列(或列的组合)以避免在聚合时混合记录,那将是很好的。我假设一个主键列名为id
.
询问:
SELECT
t.Col1,
t.Col2,
t.Col3,
t.Col4,
STRING_AGG(words.txt, ',') FoundKeywords,
STRING_AGG(
STUFF(CONCAT(
IIF(CONCAT(' ', t.Col1, ' ') LIKE CONCAT(' %', words.txt, '% '), ',Col1', ''),
IIF(CONCAT(' ', t.Col2, ' ') LIKE CONCAT(' %', words.txt, '% '), ',Col2', ''),
IIF(CONCAT(' ', t.Col3, ' ') LIKE CONCAT(' %', words.txt, '% '), ',Col3', ''),
IIF(CONCAT(' ', t.Col4, ' ') LIKE CONCAT(' %', words.txt, '% '), ',Col4', '')
), 1, 1, ''),
','
) KeywordFoundin
FROM
mytable t
INNER JOIN (
SELECT 'ABC' txt UNION ALL SELECT 'YUI' UNION ALL SELECT 'OOP'
) words
ON CONCAT(' ', t.Col1, ' ', t.Col2, ' ', t.Col3, ' ', t.col4, ' ')
LIKE CONCAT(' %', words.txt, '% ')
GROUP BY
t.id,
t.Col1,
t.Col2,
t.Col3,
t.Col4
Col1 | Col2 | Col3 | Col4 | 找到关键字 | 关键字Foundin :-------- | :-------- | :-------- | :-------- | :------------ | :------------- ABC XYZ | DFG 基尔 | YUI XYZ | ABC IOH | ABC,YUI | Col1,Col4,Col3 YDT NJK | ABC HJK | 新泽西州 XYZ | WEC OPP | 美国广播公司 | Col2
在 SQL Server < 2017 中, whereSTRING_AGG()
不可用,我会使用一个简单SELECT
的 with(非常长)表达式来比较和连接所需的信息:
SELECT
Col1,
Col2,
Col3,
Col4,
STUFF(CONCAT(
IIF(CONCAT(' ', Col1, ' ', Col2, ' ', Col3, ' ', Col4, ' ') LIKE CONCAT(' %', 'ABC', '% '), ',ABC', ''),
IIF(CONCAT(' ', Col1, ' ', Col2, ' ', Col3, ' ', Col4, ' ') LIKE CONCAT(' %', 'YUI', '% '), ',YUI', ''),
IIF(CONCAT(' ', Col1, ' ', Col2, ' ', Col3, ' ', Col4, ' ') LIKE CONCAT(' %', 'OOP', '% '), ',OOP', '')
), 1, 1, '') FoundKeywords,
STUFF(CONCAT(
IIF(
CONCAT(' ', Col1, ' ') LIKE CONCAT(' %', 'ABC', '% ')
OR CONCAT(' ', Col1, ' ') LIKE CONCAT(' %', 'YUI', '% ')
OR CONCAT(' ', Col1, ' ') LIKE CONCAT(' %', 'OOP', '% '),
',Col1',
''
),
IIF(
CONCAT(' ', Col2, ' ') LIKE CONCAT(' %', 'ABC', '% ')
OR CONCAT(' ', Col2, ' ') LIKE CONCAT(' %', 'YUI', '% ')
OR CONCAT(' ', Col2, ' ') LIKE CONCAT(' %', 'OOP', '% '),
',Col2',
''
),
IIF(
CONCAT(' ', Col3, ' ') LIKE CONCAT(' %', 'ABC', '% ')
OR CONCAT(' ', Col3, ' ') LIKE CONCAT(' %', 'YUI', '% ')
OR CONCAT(' ', Col3, ' ') LIKE CONCAT(' %', 'OOP', '% '),
',Col3',
''
),
IIF(
CONCAT(' ', Col4, ' ') LIKE CONCAT(' %', 'ABC', '% ')
OR CONCAT(' ', Col4, ' ') LIKE CONCAT(' %', 'YUI', '% ')
OR CONCAT(' ', Col4, ' ') LIKE CONCAT(' %', 'OOP', '% '),
',Col4',
''
)
), 1, 1, '') KeywordFoundin
FROM mytable
WHERE
CONCAT(' ', Col1, ' ', Col2, ' ', Col3, ' ', col4, ' ') LIKE CONCAT(' %', 'ABC', '% ')
OR CONCAT(' ', Col1, ' ', Col2, ' ', Col3, ' ', col4, ' ') LIKE CONCAT(' %', 'YUI', '% ')
OR CONCAT(' ', Col1, ' ', Col2, ' ', Col3, ' ', col4, ' ') LIKE CONCAT(' %', 'OOP', '% ')
推荐阅读
- reactjs - 在一个文件中反应 js 更多功能反应卸载
- dataframe - 计算 Yes 和 No 的 data.frame 中的单词频率
- typescript - SPFx ChartJS Web 部件
- amazon-web-services - AWS - 安全组报告 powershell
- sql - HiveQL:如何编写查询以根据嵌套的 JSON 数组值选择和过滤记录
- julia - Julia:将行向量转换为列向量
- java - 您可以使用 Dropwizard 的配置框架而无需启动网络服务器吗?
- javascript - 为什么 jQuery 的 .on() 可以工作,而原生 JavaScript 的 .addEventListener() 却不行?
- java - 如何从java中的对象数组的循环中打印出函数
- shopware - 自定义 cms 元素 SW6