如何在 sql 中使用 join ON LIKE 运算符获取结果
How to get results using join ON LIKE operator in sql
我正在尝试在单个查询中进行多个连接以从多个 table 中提取数据。
表格 - Places_main
、User_interests
、travel_list
User_interests
table 数据:
ID USERID INTERESTID
84 27 |18|
85 27 |18|
Places_main
table数据
ID TAGS
1 |5|18|35|34|33
2 |5|18|35|33|34
我想要达到的目的:
从 Places_main table 中获取不在 travel_list 中的地点列表,对于 places_main 的 "tags" 列,places_main 中有一个条目 User_interests table 在 interestID 列中。
这是查询1
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE '%' || ui.interestid || '%'
where tl.ID is null and ui.ID is null
这是与上面相同但具有硬编码数据的相同查询 2
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE '%18%'
where tl.ID is null and ui.ID is null
当我使用硬编码值执行查询时,它 returns 预期结果,但是当我 运行 没有硬编码(第一个查询)时,它 returns 没有。
如何在不使用硬编码值的情况下获得预期结果。
提前感谢您的帮助。
编辑:
如果我删除管道形式 table 数据并将其作为单个值进行比较,它工作正常。但是随着管道排成一排,它 returns 是空的。对此有何建议。
您遗漏了类似值的引号
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE '"%' || ui.interestid || '%"'
where tl.ID is null and ui.ID is null
首先,您不应该那样存储标签。您应该将 table 规范化为每行存储一个标签。然后剩下要做的就是一个简单的连接:
create table user_interests (
id int,
userid int,
interestid int
);
insert into user_interests values
(84 , 27 ,18),
(85 , 27 ,18);
create table places_main (
id int,
tag int
);
insert into places_main values
(1,5), (1,18), (1,35), (1,34), (1,33),
(2,5), (2,18), (2,35), (2,33), (2,34);
select *
from places_main p
join user_interests u on p.tag = u.interestid;
Demo normalized
对于您当前的设计,这里有一个丑陋的解决方案:
create table places_main (
id int,
tags varchar(100)
);
insert into places_main values
(1,'|5|18|35|34|33'),
(2,'|5|18|35|33|34');
select *
from places_main p
left join user_interests u
on concat('|', p.tags, '|') like concat('%|', u.interestid, '|%');
Demo
也许您的 mysql 不允许管道连接。 ||也适用于 MySQL,但您需要将 sql_mode 设置为 PIPES_AS_CONCAT。
或者你使用"concat()":
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE CONCAT('"%|', ui.interestid, '|%"')
where tl.ID is null and ui.ID is null
我正在尝试在单个查询中进行多个连接以从多个 table 中提取数据。
表格 - Places_main
、User_interests
、travel_list
User_interests
table 数据:
ID USERID INTERESTID
84 27 |18|
85 27 |18|
Places_main
table数据
ID TAGS
1 |5|18|35|34|33
2 |5|18|35|33|34
我想要达到的目的:
从 Places_main table 中获取不在 travel_list 中的地点列表,对于 places_main 的 "tags" 列,places_main 中有一个条目 User_interests table 在 interestID 列中。
这是查询1
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE '%' || ui.interestid || '%'
where tl.ID is null and ui.ID is null
这是与上面相同但具有硬编码数据的相同查询 2
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE '%18%'
where tl.ID is null and ui.ID is null
当我使用硬编码值执行查询时,它 returns 预期结果,但是当我 运行 没有硬编码(第一个查询)时,它 returns 没有。
如何在不使用硬编码值的情况下获得预期结果。
提前感谢您的帮助。
编辑:
如果我删除管道形式 table 数据并将其作为单个值进行比较,它工作正常。但是随着管道排成一排,它 returns 是空的。对此有何建议。
您遗漏了类似值的引号
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE '"%' || ui.interestid || '%"'
where tl.ID is null and ui.ID is null
首先,您不应该那样存储标签。您应该将 table 规范化为每行存储一个标签。然后剩下要做的就是一个简单的连接:
create table user_interests (
id int,
userid int,
interestid int
);
insert into user_interests values
(84 , 27 ,18),
(85 , 27 ,18);
create table places_main (
id int,
tag int
);
insert into places_main values
(1,5), (1,18), (1,35), (1,34), (1,33),
(2,5), (2,18), (2,35), (2,33), (2,34);
select *
from places_main p
join user_interests u on p.tag = u.interestid;
Demo normalized
对于您当前的设计,这里有一个丑陋的解决方案:
create table places_main (
id int,
tags varchar(100)
);
insert into places_main values
(1,'|5|18|35|34|33'),
(2,'|5|18|35|33|34');
select *
from places_main p
left join user_interests u
on concat('|', p.tags, '|') like concat('%|', u.interestid, '|%');
Demo
也许您的 mysql 不允许管道连接。 ||也适用于 MySQL,但您需要将 sql_mode 设置为 PIPES_AS_CONCAT。
或者你使用"concat()":
select * from places_main pm
LEFT JOIN travel_list tl ON pm.ID = tl.PLACEID
LEFT JOIN user_interests ui ON pm.TAGS NOT LIKE CONCAT('"%|', ui.interestid, '|%"')
where tl.ID is null and ui.ID is null