2014-12-19 88 views
1

我做了一個依賴於一堆內部選擇的查詢[因爲當我邏輯地在我們龐大的數據庫中查詢查詢的關係時,它使「邏輯」感]。用一些內部選擇重新加入MySQL查詢加入

但是,現在我想重構我的查詢以使用JOIN s代替,因爲我在博客上閱讀了嵌套選擇不利於可讀性。

/** 
* 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的初學者,我想在開始時形成一些良好的習慣。有人可以幫我或給我一些關於如何重構這個更好的可讀性的提示嗎?

謝謝。

+0

您確定您必須在此行使用'LEFT JOIN'而不是'JOIN' LEFT JOIN oc_category oc'嗎? – Hovo 2014-12-19 06:27:08

+0

我的意思是說'JOIN',我的不好。 – theGreenCabbage 2014-12-19 06:28:26

回答

1

第一步,看看這個

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 
     ) 
    ) 

下一步,讓我們改變未來level

 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 

任何人,糾正我,如果我錯了。

編輯:通過更改表前綴更改查詢到正確的一個。

+0

嗯,它似乎在你的'最後一步和最終查詢',你在MySQL中使用的結果將返回未定義的索引,意思是說,結果是一個空集。我不確定目前有什麼問題,但我正在調查。我打斷了查詢,並且空集開始返回'加入oc_category oc on(c.parent_id = oc.category_id);' – theGreenCabbage 2014-12-19 06:53:00

+0

也許原因是我們已經刪除了'LEFT JOIN'並且已經創建了它成爲'JOIN'。您是否嘗試更改'$ dish_id'變量的值? – Hovo 2014-12-19 06:59:22

+0

我明白了。我正在編輯您的更改,但我的互聯網正在愚蠢。 – theGreenCabbage 2014-12-19 06:59:50