2010-07-20 4 views
2

, 내 요리법 데이터베이스를 재구성했습니다쿼리 여러 테이블

iid | ingredient_name 
1 | self-raising flour 
2 | milk 
3 | chocolate 
4 | baking powder 
5 | plain flour 
6 | eggs 

recipe_categories

recipe_id | category_id 
    1  | 1 
    4  | 1 
    5  | 1 
    1  | 2 
    2  | 2 
    3  | 3 
    4  | 3 

recipe_ingredients

recipe_id | ingredient_id 
    1  | 1 
    2  | 1 
    4  | 1 
    1  | 2 
    2  | 2 
    3  | 2 
    5  | 2 
    1  | 3 
    2  | 3 
    1  | 4 
    3  | 5 
    4  | 5 
내 쿼리 (아마도 GROUP_CONCAT를 사용하여 성분을 분리하는
를 사용하여 나열 재료 부문별로 조리법을 반환해야

(I .ingredient_name separator '
') 출력을 어제 제안했다.

그래서, 디저트에 대한 쿼리는 것 출력 :

black forest cake: 
self-raising flour 
milk 
chocolate 

croquembouche: 
self-raising flour 
plain flour 

crepes suzette: 
milk 
plain flour 

내가 recipe_ingredients 및 조리법과 재료 및 검색 카테고리에 가입해야 알아,하지만 난 정말이 작업을 수행하는 방법에 어려움을 겪고 있어요.

답변

2

검색어 :

SELECT A.recipe_name, GROUP_CONCAT(ingredient_name) AS ingredient_names 
FROM recipes A 
LEFT JOIN recipe_ingredients B ON A.id = B.recipe_id 
LEFT JOIN ingredients C ON B.ingredient_id = C.iid 
LEFT JOIN recipe_categories D ON A.id = D.recipe_id 
LEFT JOIN categories E ON D.category_id = E.cid 
WHERE category_id = <serach_id> 
GROUP BY id 

결과 :

여기
+-------------------+-------------------------------------------------+ 
| recipe_name  | ingredient_names        | 
+-------------------+-------------------------------------------------+ 
| black forest cake | chocolate,baking powder,self-raising flour,milk | 
| angel cake  | self-raising flour,milk,chocolate    | 
| melting moments | milk,plain flour        | 
| croquembouche  | self-raising flour,plain flour     | 
| crepes suzette | milk           | 
+-------------------+-------------------------------------------------+ 

당신이 GROUP_CONCAT를 사용하여 요구 것입니다. 각 성분은 ,

+0

브릴리언트로 구분됩니다. 정말 고맙습니다! – circey

0

제대로 서식을 지정하는 방법을 알아보기 위해 맡기 겠지만, 재료 및 레서피 테이블을 함께 결합해야하지만 함께 카테고리를 검색해야합니다.

후자를 수행하는 가장 쉬운 방법은 IN 절 (EXISTS 작동)을 사용하는 것입니다. 예를 들면 : 당신이하는 바로 조리법은 하나 이상의 일치하는 범주가 포함 된 경우 여러 행을 생성합니다 가입하고, 하나 개의 카테고리를 검색하지 않는 한 그렇게 IN/EXISTS 가장

SELECT * 
FROM recipes 
LEFT OUTER JOIN recipe_ingredients ON recipe.recipe_id = recipe_ingredients.recipe_id 
WHERE recipes.id IN (SELECT recipe_categories.recipe_id 
        FROM categories 
        INNER JOIN recipe_categories ON categories.cid = recipe_categories.category_id 
        WHERE categories.category_name = @search_term) 

주입니다.

1

나는 한 번에 한 단계 씩, 당신이 그들을 깨뜨림으로써 사물을 이해할 수 있음을 발견했다.

먼저 디저트를 준비합시다.

SELECT categories.cid 
    FROM categories 
WHERE category_name = 'desserts' 

이제 사막의 모든 조리법을 결과의 왼쪽에 붙이자. 카테고리의 모든 일치하는 행에 대해 recipe_categories에 하나 이상의 일치하는 행이있을 수 있습니다. recipe_categories의 일치하는 모든 행에 대해 하나 이상의 일치하는 행이 래서 피에있을 수 있습니다.

SELECT categories.cid, recipes.recipe_name 
     FROM categories 
LEFT JOIN recipe_categories ON (recipe_categories.category_id = categories.cid) 
LEFT JOIN recipes ON (recipes.rid = recipe_categories.recipe_id) 
    WHERE category_name = 'desserts' 

마지막으로 왼쪽에 성분을 붙이겠습니다. 우리가 지금까지 가지고있는 모든 일치하는 행 (recipe_ingredients에 하나 이상의 일치 항목을 넣은 다음 다시 하나 이상의 일치 항목을 recipes에 넣을 수 있습니다)입니다.

SELECT recipes.recipe_name, ingredients.ingredient_name 
     FROM categories 
LEFT JOIN recipe_categories ON (recipe_categories.category_id = categories.cid) 
LEFT JOIN recipes ON (recipes.rid = recipe_categories.recipe_id) 
LEFT JOIN recipe_ingredients ON (recipe_ingredients.recipe_id = recipes.rid) 
LEFT JOIN ingredients ON (ingredients.iid = recipe_ingredients.ingredient_id) 
    WHERE category_name = 'desserts' 

지금까지 나와요?

지금은 늦었으며이 코드는으로 테스트하지 않았지만 찾고있는 데이터를 반환해야합니다. 실제로, 나는 완전히 잘못된 조인 유형을 사용하여 올바르게 수행 할 수 있습니다. 내가 틀렸다면 그 의견에있는 누군가가 나를 교정 할 것이라고 확신합니다.

무엇이 이되지 않습니다. 원하는대로 포맷 된 데이터가 반환됩니다. 쿼리의 마지막 반복을 만들어 일부 id 필드를 추가해 보겠습니다.

SELECT recipes.rid, recipes.recipe_name, ingredients.iid, ingredients.ingredient_name 
     FROM categories 
LEFT JOIN recipe_categories ON (recipe_categories.category_id = categories.cid) 
LEFT JOIN recipes ON (recipes.rid = recipe_categories.recipe_id) 
LEFT JOIN recipe_ingredients ON (recipe_ingredients.recipe_id = recipes.rid) 
LEFT JOIN ingredients ON (ingredients.iid = recipe_ingredients.ingredient_id) 
    WHERE category_name = 'desserts' 

다차원 배열로 데이터를 수집합시다. 우리가 PDO를 사용하고있는 것처럼 가장하자. 그 구조에서

array(
    1 => array(
     'recipe_name' => 'black forest cake', 
     'ingredients' => array(
      '1' => 'self-raising flour', 
      '2' => 'milk', 
      ... 
     ) 
    ) 
) 

, 당신은 당신이 원하는 것을 할 수 있습니다

$query = '...'; 
$sh = $db->prepare($query); 
$sh->execute(); 
$recipes = array(); 
while($row = $sh->fetch(PDO::FETCH_ASSOC)) { 
// For each row in the result set, check to see if we've looked at this recipe. 
    if(!array_key_exists($row['rid'], $recipes)) { 
    // If we haven't, let's initialize the row with the recipe name 
    // and a place to stick each ingredient. 
     $recipes[ $row['rid'] ] = array( 
      'recipe_name' => $row['recipe_name'], 
      'ingredients' => array() 
     ); 
    } 
// Place this ingredient with the proper recipe. 
    $recipes[ $row['rid'] ]['ingredients'][ $row['iid'] ] = $row['ingredient_name']; 
} 

결과는 무엇인가해야한다.