У меня есть несколько двоичных таблиц, которые, вместе взятые, моделируют данные словаря. Каждая таблица состоит из двух столбцов: «id» для идентификатора записи и «data» для описания свойства записи. Для каждой записи может быть несколько одинаковых свойств, поэтому запись с идентификатором «1» может содержать два написания, пять примеров фраз и т. Д., Все они привязаны к идентификатору записи. Как некоторые случайные данные примера:
table1:
id data
1 "a"
1 "b"
1 "c"
2 "a"
2 "x"
...
table2:
id data
1 "a"
2 "b"
...
Таблица3:
id data
1 "a"
1 "b"
2 "a"
2 "b"
2 "c"
2 "d"
...
Я хотел бы запросить эти данные, чтобы на основе поиска в таблице ... для записей со значением "a" я получил полный набор табличных значений. Скажем, например, что я хочу получить данные для всех записей со свойством table1 "a", которое даст список идентификаторов {1,2}. Я бы хотел получить результаты
результат:
id t1prop trprop t3prop
1 a, b, c a a, b
2 a, x b a, b, c, d
Получение всех соответствующих идентификаторов из одной таблицы тривиально,
SELECT DISTINCT id FROM table1 WHERE data LIKE "a"
Но как мне использовать этот результат в большем выборе? Если я попытаюсь соединить это с таблицей2 на «id», я не могу свернуть table2.data в одну строку, как вы можете сделать с помощью GROUP_CONCAT, так как я могу убедиться, что есть только один результат для каждого отдельного идентификатора с несколькими записями за таблицу, свернутую в (в данном случае запятую) разделенные списки?
Я пытался посмотреть, смогу ли я просто объединить две или более таблиц, что работает для двух:
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
Для более чем двух таблиц это не свернет все значения 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 INT NOT NULL, data TEXT)
Нет столбцов INDEX, мотивированных в основном тем, что это данные словаря JP-> EN. Индексирование английской таблицы в основном делает возможным индексирование целых абзацев текста, что не идеально, и MySQL не может индексировать японский язык из-за ограничения минимальной длины индекса (минимум 3 буквы имеют смысл для английского, но большинство японских слов состоят только из одного или двух глифов, поэтому они никогда не индексируются). Я мог бы установить таблицу идентификаторов в качестве индекса, но, поскольку это уже INT, кажется, не имеет особого смысла.
(первичных ключей также нет, поскольку идентификаторы не являются уникальными идентификаторами в этих таблицах)
MySQL объясняет мой вложенный выбор следующим образом:
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
| 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 |
+----+-------------+----------------+------+---------------+------+---------+------+--------+---------------------------------+
(размеры таблиц dictionary_eng: 268512 записей, dictionary_keb: 182366 записей, dictionary_reb: 172755 записей)