Рефакторинг запроса MySQL с несколькими внутренними выборами для объединения

63
7

Я сделал запрос, который опирался на кучу внутренних selects [поскольку, когда я логически разрабатывал отношения запроса в нашей обширной базе данных, он сделал "логический" смысл].

Тем не менее, прямо сейчас я хочу реорганизовать свой запрос на использование JOIN вместо этого, так как я читал в блоге, что вложенные selects не подходят для удобочитаемости.

/**
* Returns the city area ID based on the dish
* @param $dish_id ID of the dish
* @return mixed City area ID
*/
public function getCityAreaByDishId(
$dish_id
) {
$query = $this->db->query("
SELECT
m.city_area_id as city_area_id
FROM menus m
WHERE m.id = (
SELECT c.menu_id
FROM oc_category c
WHERE category_id = (
SELECT oc.category_id
FROM oc_category c
LEFT JOIN oc_category oc
ON (c.parent_id = oc.category_id)
WHERE c.category_id = (
SELECT ptc.category_id
FROM oc_product_to_category ptc
WHERE ptc.product_id = $dish_id
)
)
);
");
return $query->row['city_area_id'];
}

Я новичок в MySQL, и я хочу создать хорошие привычки в начале. Может ли кто-нибудь помочь мне или дать мне несколько советов о том, как реорганизовать это для лучшей читаемости?

Спасибо.

спросил(а) 2021-01-25T18:04:11+03:00 4 месяца, 2 недели назад
1
Решение
63

Первый шаг, посмотрите на это

SELECT oc.category_id
FROM oc_category c
JOIN oc_category oc
ON (c.parent_id = oc.category_id)
WHERE c.category_id = (
SELECT ptc.category_id
FROM oc_product_to_category ptc
WHERE ptc.product_id = $dish_id
)

его можно изменить на

SELECT oc.category_id
FROM oc_category c
JOIN oc_category oc ON (c.parent_id = oc.category_id)
JOIN oc_product_to_category ptc ON ptc.category_id = c.category_id AND ptc.product_id = $dish_id

поэтому весь запрос будет

    SELECT m.city_area_id as city_area_id
FROM menus m
WHERE m.id = (
SELECT c.menu_id
FROM oc_category c
WHERE category_id = (
SELECT oc.category_id
FROM oc_category c
JOIN oc_category oc ON (c.parent_id = oc.category_id)
JOIN oc_product_to_category ptc ON ptc.category_id = c.category_id AND ptc.product_id = $dish_id
)
)

Следующий шаг - изменить следующий уровень

        SELECT c.menu_id
FROM oc_category c
WHERE category_id = (
SELECT oc.category_id
FROM oc_category c
JOIN oc_category oc ON (c.parent_id = oc.category_id)
JOIN oc_product_to_category ptc ON ptc.category_id = c.category_id AND ptc.product_id = $dish_id

в

        SELECT c.menu_id
FROM oc_category c
JOIN oc_category oc ON (c.parent_id = oc.category_id)
JOIN oc_product_to_category ptc ON ptc.category_id = c.category_id AND ptc.product_id = $dish_id

поэтому запрос становится

SELECT m.city_area_id AS city_area_id
FROM menus m
WHERE m.id = (
SELECT c.menu_id
FROM oc_category c
JOIN oc_category oc ON (c.parent_id = oc.category_id)
JOIN oc_product_to_category ptc ON ptc.category_id = c.category_id AND ptc.product_id = $dish_id
)

Последний шаг и окончательный запрос

SELECT m.city_area_id AS city_area_id
FROM menus m
JOIN oc_category c ON (m.id = c.menu_id)
JOIN oc_category oc ON (oc.parent_id = c.category_id)
JOIN oc_product_to_category ptc ON ptc.category_id = oc.category_id AND ptc.product_id = $dish_id

Кто-нибудь, исправьте меня, если я ошибаюсь.

EDIT: изменил запрос вправо, изменив префиксы таблицы.

ответил(а) 2021-01-25T18:04:11+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема