我有两张桌子。
首先包含使用过的单词列表,然后保留不能显示的单词黑名单。
第一个表(A)示例
+---------------+
| keyword |
+---------------+
| php |
| php developer |
| developer |
| c# |
+---------------+
第二个表(B)示例:
+-----------+
| word |
+-----------+
| developer |
| foo |
| music |
+-----------+
我必须显示第一个表中的所有内容,除了完全或部分包含第二个表中的单词的行。 例如,基于上面的内容,我应该只显示两行 php和c#。
我如何通过帮助SQL获得相同的结果(非常好,如果它将是一个)
我只能做这个
select * from A where keyword not in(select word from B);
但这是严格的比较。这对我来说还不够。
欢迎任何建议。 感谢。
答案 0 :(得分:4)
你想:
SELECT keyword FROM A
WHERE NOT EXISTS (
SELECT TOP 1 1 FROM B
WHERE A.keyword LIKE '%' + B.word + '%' )
请注意,在术语开头使用%
执行此类查询会导致B.word
上的索引无法使用。
我的测试代码(使用SQL Server,因此表格声明用于测试是TSQL但仍然相关):
DECLARE @A TABLE
(
keyword varchar(50)
)
DECLARE @B TABLE
(
word varchar(50)
)
INSERT INTO @A VALUES ('php'), ('php developer'), ('Developer'), ('C#')
INSERT INTO @B VALUES ('developer'), ('fcuk'), ('music')
SELECT keyword FROM @A A WHERE NOT EXISTS (SELECT TOP 1 1 FROM @B B WHERE a.keyword LIKE '%' + B.word + '%')
结果:
keyword
php
C#
编辑:更多解释:
此查询是查询的逻辑扩展名:
select * from A
where keyword not in(
select word from B);
可以写成以下内容(逻辑上完全相同):
SELECT * FROM A
WHERE NOT EXISTS (
SELECT * FROM B
WHERE A.keyword = B.word)
我们想要做的是排除A.keyword contains
B.Word
值所在的记录。这是通过预先挂起并附加'%'
字符并执行LIKE
而不是=
因此查询变为:
SELECT * FROM A
WHERE NOT EXISTS (
SELECT * FROM B
WHERE A.keyword LIKE = '%' + B.word + '%')
SELECT 1 1
只是毫无意义,如果您愿意,它们同样可以是SELECT *
,它们都是EXISTS
语句中的相同内容,而StackOverflow上有很多答案专门解释原因他们是一样的。
答案 1 :(得分:3)
这将是这样的:
select keyword from A where keyword not in
(select A.keyword from A
inner join B on A.keyword like '%' + B.keyword + '%')
您选择A中包含B字的所有单词,然后选择其他单词。