Обходной путь из исходного запроса:
SELECT * FROM parent
JOIN child ON child.ch_pa_id = parent.pa_id
AND child.ch_id IN
(SELECT ch_id FROM (
SELECT child.ch_id FROM child JOIN parent
WHERE child.ch_id = parent.pa_id
LIMIT 3) a
)
ORDER BY parent.pa_id;
Сохранение исходной операции подзапроса для извлечения ch_id
из дочерней таблицы с помощью LIMIT 3
, однако, путем добавления таблицы parent
в объединение.Затем выполните другую операцию, чтобы получить результат подзапроса, затем используйте его для вашего IN
.
РЕДАКТИРОВАТЬ: У меня есть рабочий запрос, но у меня смешанные чувства по этому поводу:
SELECT * FROM parent
JOIN child ON parent.pa_id=child.ch_pa_id
LEFT JOIN (
SELECT ch_pa_id,SUBSTRING_INDEX(chid,' ',1) f,SUBSTRING_INDEX(chid,' ',-1) e
FROM (
SELECT ch_pa_id,
SUBSTRING_INDEX(GROUP_CONCAT(ch_id ORDER BY ch_id ASC SEPARATOR ' '),' ',3) chid
FROM child
GROUP BY ch_pa_id) a) b
ON child.ch_pa_id=b.ch_pa_id
WHERE child.ch_id
BETWEEN f AND e;
Честно говоря, я боюсь, что это не будет хорошо работать с большими данными, но я всегда изучаю что-то новое и некоторые из функций, которые я только недавно обнаружил.
Согласно вашей скрипке, я замечаю, что вы берете только первые 3 ch_id
для каждого родителя.Следовательно, это SUBSTRING_INDEX(GROUP_CONCAT(ch_id ORDER BY ch_id ASC SEPARATOR ' '),' ',3) chid
.GROUP_CONCAT
для отображения данных по горизонтали и SUBSTRING_INDEX
для получения первых 3 ch_id
в сборке.Обычно group_concat возвращает значение как таковое;1,2,3
и substring_index могут идентифицировать только первое, второе и т. Д. Значение, разделенное [пробел] ('').Вот почему я добавил SEPARATOR ' '
.
Затем я использую SUBSTRING_INDEX
дважды для внешнего запроса, чтобы определить f
и e
, где SUBSTRING_INDEX(chid,' ',1)
, чтобы получить первое значение, и SUBSTRING_INDEX(chid,' ',-1)
, чтобы получитьпоследнее значение из столбца.И с этим я присоединяюсь к исходному запросу и добавляю BETWEEN f and e
.