Mysql 如何基于从一个二进制表中获取的ID列表来连接多个二进制表
我有几个二进制表,它们合在一起为字典数据建模。每个表由两列组成,“id”表示条目标识符,“data”表示条目属性。每个条目可以有多个相似的属性,因此id为“1”的条目可以有两个拼写、五个示例短语等,所有这些都键入条目id。作为一些随机示例数据: 表1:Mysql 如何基于从一个二进制表中获取的ID列表来连接多个二进制表,mysql,sql,Mysql,Sql,我有几个二进制表,它们合在一起为字典数据建模。每个表由两列组成,“id”表示条目标识符,“data”表示条目属性。每个条目可以有多个相似的属性,因此id为“1”的条目可以有两个拼写、五个示例短语等,所有这些都键入条目id。作为一些随机示例数据: 表1: id data 1 "a" 1 "b" 1 "c" 2 "a" 2 "x" ... 表2: id data 1 "a" 2 "b" ... 表3: id data 1
id data
1 "a"
1 "b"
1 "c"
2 "a"
2 "x"
...
表2:
id data
1 "a"
2 "b"
...
表3:
id data
1 "a"
1 "b"
2 "a"
2 "b"
2 "c"
2 "d"
...
我想查询这些数据,以便根据表中的搜索。。。对于值为“a”的条目,我得到了表的完整值集。比如说,我想要table1属性为“a”的所有条目的数据,这将给出id{1,2}的列表。我想要的结果是
结果:
id t1prop trprop t3prop
1 a, b, c a a, b
2 a, x b a, b, c, d
从一个表中获取所有相关ID非常简单
SELECT DISTINCT id FROM table1 WHERE data LIKE "a"
但是我如何在更大的选择中使用这个结果呢?如果我尝试将其与“id”上的table2连接起来,我似乎无法像使用GROUP_CONCAT那样将table2.data折叠成一行,那么我如何确保每个不同的id只有一个结果,每个表的多个条目折叠成(在本例中为逗号)分隔的列表
我试着看看是否可以连接两个或多个表,这对两个表都有效:
SELECT
t1.id AS id,
GROUP_CONCAT(DISTINCT t2.data SEPARATOR ', ') AS t2properties,
FROM
(SELECT DISTINCT id FROM table1 WHERE data LIKE "a") AS t1
JOIN table2 AS t2 ON t1.id=t2.id
GROUP BY t2.data
但不适用于超过两种情况:
SELECT
t1.id AS id,
GROUP_CONCAT(DISTINCT t2.data SEPARATOR ', ') AS t2properties,
GROUP_CONCAT(DISTINCT t3.data SEPARATOR ', ') AS t3properties
FROM
(SELECT DISTINCT id FROM table1 WHERE data LIKE "a") AS t1
JOIN table2 AS t2 ON t1.id=t2.id
JOIN table3 AS t3 ON t1.id=t3.id
GROUP BY t2.data, t3.data
对于两个以上的表,这不会将一个id的所有table2.data和table3.data值折叠为一行。我还尝试将其作为嵌套选择序列来执行,但这只会使查询运行时间非常长
我不知道这种选择叫什么,所以我在谷歌搜索如何解决这个问题时完全失败了(可能是很久以前)。如果有人知道如何做到这一点,或者知道在其他地方搜索什么来找到如何做到这一点,我将非常感谢任何帮助
更新
我使用实际表名尝试的完整嵌套选择如下所示:
SELECT
keb.id AS id,
english,
reading,
GROUP_CONCAT(DISTINCT keb.data SEPARATOR ', ') AS kanji
FROM
(SELECT
eng.id AS id,
english,
GROUP_CONCAT(DISTINCT reb.data SEPARATOR ', ') AS reading
FROM
(SELECT
DISTINCT id,
GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS english
FROM dictionary_eng
WHERE (data LIKE "%tiger%")
GROUP BY id
ORDER BY id
) AS eng
JOIN dictionary_reb AS reb ON eng.id=reb.id
GROUP BY eng.id
ORDER BY eng.id
) AS reb
JOIN dictionary_keb AS keb ON reb.id=keb.id
GROUP BY keb.id
ORDER BY keb.id
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 77 | Using temporary; Using filesort |
| 1 | PRIMARY | keb | ALL | NULL | NULL | NULL | NULL | 185054 | Using where; Using join buffer |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 77 | Using temporary; Using filesort |
| 2 | DERIVED | reb | ALL | NULL | NULL | NULL | NULL | 178085 | Using where; Using join buffer |
| 3 | DERIVED | dictionary_eng | ALL | NULL | NULL | NULL | NULL | 262929 | Using filesort |
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
表格定义如下:
(id INT NOT NULL, data TEXT)
没有索引列,主要是因为这是JP->EN字典数据。对英文表进行索引基本上使其对整个文本段落进行索引,这并不理想,而MySQL由于其最小索引长度限制而无法对日语进行索引(至少3个字母对英语来说非常有意义,但大多数日语单词只包含一个或两个glyph,因此它们永远不会被索引)。我可以将id表设置为一个索引,但由于它已经是INT,这似乎没有多大意义
(也没有主键,因为这些表中的ID不是唯一标识符)
MySQL对我的嵌套选择的解释如下:
SELECT
keb.id AS id,
english,
reading,
GROUP_CONCAT(DISTINCT keb.data SEPARATOR ', ') AS kanji
FROM
(SELECT
eng.id AS id,
english,
GROUP_CONCAT(DISTINCT reb.data SEPARATOR ', ') AS reading
FROM
(SELECT
DISTINCT id,
GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS english
FROM dictionary_eng
WHERE (data LIKE "%tiger%")
GROUP BY id
ORDER BY id
) AS eng
JOIN dictionary_reb AS reb ON eng.id=reb.id
GROUP BY eng.id
ORDER BY eng.id
) AS reb
JOIN dictionary_keb AS keb ON reb.id=keb.id
GROUP BY keb.id
ORDER BY keb.id
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 77 | Using temporary; Using filesort |
| 1 | PRIMARY | keb | ALL | NULL | NULL | NULL | NULL | 185054 | Using where; Using join buffer |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 77 | Using temporary; Using filesort |
| 2 | DERIVED | reb | ALL | NULL | NULL | NULL | NULL | 178085 | Using where; Using join buffer |
| 3 | DERIVED | dictionary_eng | ALL | NULL | NULL | NULL | NULL | 262929 | Using filesort |
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
|id |选择|类型|类型|可能的|键|键|列|参考|行|额外|
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
|1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | NULL | 77 |使用临时命令;使用文件排序|
|1 | PRIMARY | keb | ALL | NULL | NULL | NULL | NULL | NULL | 185054 |使用where;使用连接缓冲区|
|2 |派生| |所有|空|空|空|空| 77 |使用临时变量;使用文件排序|
|2 |派生| reb | ALL | NULL | NULL | NULL | NULL | 178085 |使用where;使用连接缓冲区|
|3 |派生|字典|全部|空|空|空|空| 262929 |使用文件排序|
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
(表格大小为dictionary_eng:268512记录、dictionary_keb:182366记录、dictionary_reb:172755记录)尝试以下方法:
SELECT
T1.id,
T1.properties AS t1properties,
T2.properties AS t2properties,
T3.properties AS t3properties
FROM
(
SELECT id, GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS properties
FROM table1
GROUP BY id
) T1
JOIN
(
SELECT id, GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS properties
FROM table2
GROUP BY id
) T2
ON T1.id = T2.id
JOIN
(
SELECT id, GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS properties
FROM table3
GROUP BY id
) T3
ON T2.id = T3.id
试试这个:
SELECT
T1.id,
T1.properties AS t1properties,
T2.properties AS t2properties,
T3.properties AS t3properties
FROM
(
SELECT id, GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS properties
FROM table1
GROUP BY id
) T1
JOIN
(
SELECT id, GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS properties
FROM table2
GROUP BY id
) T2
ON T1.id = T2.id
JOIN
(
SELECT id, GROUP_CONCAT(DISTINCT data SEPARATOR ', ') AS properties
FROM table3
GROUP BY id
) T3
ON T2.id = T3.id
我不是mysql用户,但看看这个,你能做到以下几点:
1.使用GROUP_CONCAT创建三个单独的视图
vTable01道具
vTable02道具
vTable03道具
2.从表1、表2和表3创建不同ID的联合视图
3.写一个查询,将这四个视图左键连接到ID上
我不是mysql用户,但看看这个,你能做到以下几点:
1.使用GROUP_CONCAT创建三个单独的视图
vTable01道具
vTable02道具
vTable03道具
2.从表1、表2和表3创建不同ID的联合视图
3.编写一个查询,将这四个视图左连接到ID上,遗憾的是,这实际上需要比嵌套的select更长的时间来解析。17秒用于嵌套选择,24秒用于顺序联接。@Mike'Pomax'Kamermans:你们有什么索引?你能发布
EXPLAIN SELECT…
以获取相关查询吗?我已经更新了原始帖子,以便它现在包含这些信息。我不确定我是否完全理解id不应该有索引的原因。它不需要是唯一的,索引就可以提供帮助。你能试试吗?我想你是对的,在id列上有一个索引确实可以加快速度,尽管两次通过“查找所有id”后接“为每个表选择*id在(列表)中的位置”仍然要快得多。我想我会将它作为单独的查询保留,而不是一直尝试将其折叠为单个查询=/遗憾的是,这实际上需要比嵌套的select更长的时间来解析。17秒用于嵌套选择,24秒用于顺序联接。@Mike'Pomax'Kamermans:你们有什么索引?你能发布EXPLAIN SELECT…
以获取相关查询吗?我已经更新了原始帖子,以便它现在包含这些信息。我不确定我是否完全理解id不应该有索引的原因。它不需要是唯一的,索引就可以提供帮助。你能试试吗?我想你是对的,在id列上有一个索引确实可以加快速度,尽管两次通过“查找所有id”,然后是“为每个表选择*id所在的位置(列表)”