Mysql 根据嵌套查询的结果替换sql查询中的值

Mysql 根据嵌套查询的结果替换sql查询中的值,mysql,sql,Mysql,Sql,我有两个表:请求表和位置表 请求的样本数据 request id | requestor | locations 1 | ankur | 2,5 2 | akshay | 1 3 | avneet | 3,4 4 | priya | 4 位置的示例数据 loc_id | loc_name | 1 | gondor 2

我有两个表:请求表和位置表

请求的样本数据

request id | requestor | locations
     1     |   ankur   |   2,5
     2     |   akshay  |   1  
     3     |   avneet  |   3,4
     4     |   priya   |   4     
位置的示例数据

loc_id     |  loc_name |
     1     |  gondor   
     2     |  rohan
     3     |  mordor   
     4     |  bree   
     5     |  shire    
我想查找特定位置的请求id。如果我使用location_id执行此操作,则会得到正确的结果

select request_id from request where locations like "%,3%" or locations like "%3,%";
此查询为我提供了针对位置id=3的请求

我如何才能为loc_名称实现这一点?将查询“like”部分中的数字替换为

select loc_id from locations where loc_name = "mordor"

这方面的任何帮助都会非常有用。谢谢。

如果位置是varchar字段,则解决方案

用一个相似的字符串连接表(在r.locations处用逗号开头和结尾)

代码未经测试:

SELECT
    r.request_id
FROM location l
INNER JOIN request r
    ON CONCAT(',', r.locations, ',') LIKE CONCAT('%,',l.loc_id,',%')
WHERE l.loc_name = 'mordor'

如果位置是varchar字段,则解决方案

用一个相似的字符串连接表(在r.locations处用逗号开头和结尾)

代码未经测试:

SELECT
    r.request_id
FROM location l
INNER JOIN request r
    ON CONCAT(',', r.locations, ',') LIKE CONCAT('%,',l.loc_id,',%')
WHERE l.loc_name = 'mordor'

您可以使用
FIND\u IN\u SET()

这里是演示

但是,您最好通过引入一个看起来像的多对多表来规范化数据

CREATE TABLE request_location
(
  request_id INT NOT NULL,
  loc_id INT NOT NULL,
  PRIMARY KEY (request_id, loc_id),
  FOREIGN KEY (request_id) REFERENCES request (request_id),
  FOREIGN KEY (loc_id) REFERENCES locations (loc_id)
);
SELECT *
  FROM request_location rl JOIN request r 
    ON rl.request_id = r.request_id JOIN locations l
    ON rl.loc_id = l.loc_id
 WHERE l.loc_name = 'mordor'
从长远来看,这将带来巨大的回报,使您能够正常地维护和查询数据

那么您的查询可能如下所示

CREATE TABLE request_location
(
  request_id INT NOT NULL,
  loc_id INT NOT NULL,
  PRIMARY KEY (request_id, loc_id),
  FOREIGN KEY (request_id) REFERENCES request (request_id),
  FOREIGN KEY (loc_id) REFERENCES locations (loc_id)
);
SELECT *
  FROM request_location rl JOIN request r 
    ON rl.request_id = r.request_id JOIN locations l
    ON rl.loc_id = l.loc_id
 WHERE l.loc_name = 'mordor'
甚至

SELECT rl.request_id
  FROM request_location rl JOIN locations l
    ON rl.loc_id = l.loc_id
 WHERE l.loc_name = 'mordor';
如果您只需要返回
请求\u id


下面是演示

您可以使用
在集合中查找()

这里是演示

但是,您最好通过引入一个看起来像的多对多表来规范化数据

CREATE TABLE request_location
(
  request_id INT NOT NULL,
  loc_id INT NOT NULL,
  PRIMARY KEY (request_id, loc_id),
  FOREIGN KEY (request_id) REFERENCES request (request_id),
  FOREIGN KEY (loc_id) REFERENCES locations (loc_id)
);
SELECT *
  FROM request_location rl JOIN request r 
    ON rl.request_id = r.request_id JOIN locations l
    ON rl.loc_id = l.loc_id
 WHERE l.loc_name = 'mordor'
从长远来看,这将带来巨大的回报,使您能够正常地维护和查询数据

那么您的查询可能如下所示

CREATE TABLE request_location
(
  request_id INT NOT NULL,
  loc_id INT NOT NULL,
  PRIMARY KEY (request_id, loc_id),
  FOREIGN KEY (request_id) REFERENCES request (request_id),
  FOREIGN KEY (loc_id) REFERENCES locations (loc_id)
);
SELECT *
  FROM request_location rl JOIN request r 
    ON rl.request_id = r.request_id JOIN locations l
    ON rl.loc_id = l.loc_id
 WHERE l.loc_name = 'mordor'
甚至

SELECT rl.request_id
  FROM request_location rl JOIN locations l
    ON rl.loc_id = l.loc_id
 WHERE l.loc_name = 'mordor';
如果您只需要返回
请求\u id

这里是演示

试试这个

SELECT  *
FROM    request 
        CROSS JOIN
        (
        SELECT  1 AS loc
        UNION ALL
        SELECT  2 AS loc
        UNION ALL
        SELECT  3 AS loc
        UNION ALL
        SELECT  4 AS loc
        UNION ALL
        SELECT  5 AS loc
        ) q
JOIN    Location
ON      loc_id  = CAST(NULLIF(SUBSTRING_INDEX(locations, ',', -loc), SUBSTRING_INDEX(locations, ',', 1 - loc)) AS UNSIGNED)
试试这个

SELECT  *
FROM    request 
        CROSS JOIN
        (
        SELECT  1 AS loc
        UNION ALL
        SELECT  2 AS loc
        UNION ALL
        SELECT  3 AS loc
        UNION ALL
        SELECT  4 AS loc
        UNION ALL
        SELECT  5 AS loc
        ) q
JOIN    Location
ON      loc_id  = CAST(NULLIF(SUBSTRING_INDEX(locations, ',', -loc), SUBSTRING_INDEX(locations, ',', 1 - loc)) AS UNSIGNED)