【问题标题】:MySQL query parameters in a table field表字段中的 MySQL 查询参数
【发布时间】:2020-11-17 08:01:47
【问题描述】:

下午好。
我有两张桌子:

1 - table1 - (id, address, who_lives) who_lives 字段 - 文本,以逗号分隔的标识符列表

2 - table2 - (id, name_of_resident)
表1的组成

12|美国俄勒冈 | 12,13 14|美国华盛顿| 9,11

表2的组成

9 |彼得罗夫
11|西多罗夫
12|伊万诺夫
13|波波夫

如何使 MySQL 请求,最好是通过连接,结果是

美国俄勒冈州|伊万诺夫,波波夫
美国华盛顿|彼得罗夫,西多罗夫

如果可能,将逗号替换为 br 标签:Ivanov,Popov -> Ivanov >br

【问题讨论】:

  • FIND_IN_SET()、GROUP BY、GROUP_CONCAT()。
  • 但我建议您规范化您的数据并避免使用 CSV。
  • FIND_IN_SET 不适合 - 只能选择一列。
    SELECT t1.*, GROUP_CONCAT(t2.name_of_resident) FROM table1 t1, table2 t2 WHERE t2.id IN ( SELECT who_lives FROM table1 t3 WHERE t3.id=t1.id ) GROUP BY t1.id
    只返回一个名称
  • 您的 WHERE IN 将无法正常工作 - 它只会过滤 CSV 中第一个元素的行。

标签: mysql join select


【解决方案1】:
SELECT table1.address, GROUP_CONCAT(table2.name_of_resident SEPARATOR '<br>')
FROM table1
JOIN table2 ON FIND_IN_SET(table2.id, table1.who_lives)
GROUP BY table1.address

DEMO

【讨论】:

  • @antarey 记住 - 这是全扫描,所以性能会很差。
  • 您建议创建另一个表吗?
  • @antarey 注意Andreas Wederbrand的回答。这是非常非常有用的。在行数低于 ~1k 之前,您的非规范化结构非常安全。
  • 我同意。再次感谢
【解决方案2】:

这不是您设计表格的方式。不要做逗号分隔的列表。执行从表 2 到表 1 的(外)键,或为每个关系创建具有 table1.id 和 table2.id 的表。

那么编写查询会更容易。

create table state (
  state_id int primary key,
  address varchar(255)
);
  
create table resident (
  resident_id int primary key,
  name varchar(255)
);

create table who_lives (
  state_id int,
  resident_id int,
  primary key (state_id, resident_id)
);

insert into state values (12, 'US Oregon');
insert into state values (14, 'US Washington');
  
insert into resident values (9, 'Petrov');
insert into resident values (11, 'Sidorov');
insert into resident values (12, 'Ivanov');
insert into resident values (13, 'Popov');

insert into who_lives values (12, 12);
insert into who_lives values (12, 13);
insert into who_lives values (14, 9);
insert into who_lives values (14, 11);

select address, group_concat(name)
 from state
 join who_lives using (state_id)
 join resident using (resident_id)
 group by state_id;
 

http://sqlfiddle.com/#!9/e7041f/2

【讨论】:

  • 不,所以我说“不要使用逗号分隔的列表”。
  • 谢谢。您的解决方案是正确的,但我不想创建另一个表。
  • 如何重做请求?我无法更改前两个表的结构创建表状态( id int primary key, address varchar(255) );创建表常驻( id int 主键,名称 varchar(255) ); select address, group_concat(name) from state join who_lives using (state_id ???) join resident using (resident_id ???) group by state_id;
  • 我想通了。替换使用 with on
猜你喜欢
  • 1970-01-01
  • 2021-05-27
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-30
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
相关资源
最近更新 更多