@Depleted

Как правильно использовать REPLACE при LEFT JOIN в MySQL?

Добрый день!

Имеется 3 таблицы MySQL:

1) pages:
id | template
1 | 1


2) templates:
id | value
1 | {{> header}} {{> content}} {{> footer}}


3) parts:
id | name | value
1 | header | <html><head><title>Заголовок</title></head><body>
2 | content | <main>...</main>
3 | footer | </body></html>


Пытаюсь получить в ответ строку в виде:
id | template
1 |
<html><head><title>Заголовок</title></head><body><main>...</main></body></html>


Пришел к следующему виду запроса:
SELECT p.id, REPLACE(t.value, p2.name, p2.value) AS template
FROM `pages` AS p
LEFT JOIN `templates` AS t ON (t.id = p.template)
LEFT JOIN `parts` AS p2 ON (t.value LIKE CONCAT("%{{> ", p2.name, "}}%"))
WHERE
r.id = 1;


На выходе получаю:
id | template
1 |
<html><head><title>Заголовок</title></head><body>{{> content}}{{> footer}}

1 | {{> header}}<main>...</main>{{> footer}}
1 | {{> header}}{{> content}}</body></html>


Насколько понимаю, данная ситуация вызвана некорректным сочетанием REPLACE и JOIN`а, т.к. если группировать результат по p.id, то в ответ приходит только 1 строка с корректно замененным только {{> header}}.
Буду рад помощи, наставлениям, подсказкам или решению.

Вложенный REPLACE вопрос не решает.

P.S. Заранее всем спасибо!)
  • Вопрос задан
  • 75 просмотров
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Для MySQL 8.0 и выше:
WITH RECURSIVE `subs` (`name`, `value`, `order`) AS (
  SELECT CONCAT('{{> ', `p`.`name`, '}}'), `p`.`value`, ROW_NUMBER() OVER ()
    FROM `templates` AS `t`
    JOIN `parts` AS `p`
      ON `t`.`value` LIKE CONCAT('%{{> ', `p`.`name`, '}}%')
    WHERE `t`.`id` = 1
),
`result` (`value`, `order`) AS (
  SELECT `value`, 0
    FROM `templates`
    WHERE `id` = 1
  UNION SELECT REPLACE(`r`.`value`, `s`.`name`, `s`.`value`), `s`.`order`
    FROM `result` AS `r`
    JOIN `subs` AS `s`
      ON `s`.`order` = `r`.`order` + 1
)
SELECT `value`
  FROM `result`
  ORDER BY `order` DESC
  LIMIT 1

Для старых версий даже пробовать не буду, мне столько не выпить.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы