2016-12-09 4 views
0

次のクエリは、スープのリストと各スープのリストを表示します。GROUP_CONCATとLEFT_JOIN - フィルターレコード

 //Query only for demonstration 

    SELECT a.id_soup, a.soup,  
    GROUP_CONCAT(DISTINCT b.id_vegetables) AS vegetables_id, 
    GROUP_CONCAT(DISTINCT b.vegetables) AS vegetables_list 
    FROM soups a 
    LEFT JOIN ingredients ing ON a.soup = ing.soup_id 
    LEFT JOIN vegetables b ON b.id_vegetables = ing.list_vegetables 
    GROUP BY a.id_soup 

スープに特定の成分(ジャガイモなど)があるものだけが表示されるようにレコードをフィルタリングしたいと考えています。ような何か:

 SELECT a.id_soup, a.soup,  
    GROUP_CONCAT(DISTINCT b.id_vegetables) AS vegetables_id, 
    GROUP_CONCAT(DISTINCT b.vegetables) AS vegetables_list 
    FROM soups a 
    LEFT JOIN ingredients ing ON a.soup = ing.soup_id 
    LEFT JOIN vegetables b ON b.id_vegetables = ing.list_vegetables 

    AND ing.list_vegetables LIKE "potatoes" 

    GROUP BY a.id_soup 

これらのクエリは、レコードをフィルタませんが、食材のリストは、もはや単なる原料のジャガイモを表示し、スープのすべての成分を表示します。

これを正しく行うにはどのような方法が最適ですか?

EDITED:

複数の条件付き - PHPとSQL:

$typesQuery = ""; 
    $bind=array(); 

    sqlQuery = "SELECT a.id_soup, a.soup, a.restaurant,  
    GROUP_CONCAT(DISTINCT b.id_vegetables) AS vegetables_id, 
    GROUP_CONCAT(DISTINCT b.vegetables) AS vegetables_list 
    FROM soups a 
    LEFT JOIN ingredients ing ON a.soup = ing.soup_id 
    LEFT JOIN vegetables b ON b.id_vegetables = ing.list_vegetables "; 

if($restaurant) { 
    $sqlQuery .= " AND a.restaurant LIKE ? "; 
    $typesQuery .= "s" ; 
    $bind[] = $restaurant; 
} 


if($vegetables) { 
    $sqlQuery .= " AND ... "; 
    $typesQuery .= "s" ; 
    $bind[] = $vegetables; 
} 

//EDITED: 
$vegetables = 'potatoes'; 
if($vegetables) { 
    $sqlQuery .= " HAVING SUM(CASE WHEN b.vegetables IN (?) THEN 1 ELSE 0 END) = 1 "; 
    $typesQuery .= "s" ; 
    $bind[] = $vegetables; 
} 


$sqlQuery .= " GROUP BY a.id_soup LIMIT ?,? "; 

if ($statementQuery = $conexion->prepare($sqlQuery)){ 

    $typesTotal = $typesQuery; 
    $bindTotal = array_merge(array(), $bind); 

    $typesQuery .= "ii"; 
    $bind[] = $start; 
    $bind[] = $limit; 
    array_unshift($bind, $typesQuery); 
    call_user_func_array( array($statementQuery, 'bind_param'), makeValuesReferenced($bind)); 

}else{ 
    $error = $conexion->error; 
    $success = false; 
    break; 
} 
    ... 

答えて

2

使用FIND_IN_SETあなたは野菜のリストを取得した後。

SELECT * FROM (
SELECT a.id_soup, 
GROUP_CONCAT(DISTINCT b.id_vegetables) AS vegetables_id, 
GROUP_CONCAT(DISTINCT b.vegetables) AS vegetables_list 
FROM soups a 
LEFT JOIN ingredients ing ON a.soup = ing.soup_id 
LEFT JOIN vegetables b ON b.id_vegetables = ing.list_vegetables 
GROUP BY a.id_soup 
) X 
WHERE FIND_IN_SET('POTATOES',VEGETABLES_LIST) > 0 
+0

私のポストの単純な例であなたのソリューションをテストしていて、うまくいきます。しかし、複数の条件でフィルタリングしているので、私は実際のケースには適用できませんでした。私は自分の投稿を編集しました。これ以上の提案があれば、事前に感謝します。 – josei

1

おそらく単なる条件付きの節ですか?

SELECT a.id_soup, a.soup,  
GROUP_CONCAT(DISTINCT b.id_vegetables) AS vegetables_id, 
GROUP_CONCAT(DISTINCT b.vegetables) AS vegetables_list 

FROM soups a 
LEFT JOIN ingredients ing ON a.soup = ing.soup_id 
LEFT JOIN vegetables b ON b.id_vegetables = ing.list_vegetables 
GROUP BY a.id_soup 
HAVING sum(case when b.vegetables in ('potatoes') then 1 else 0 end) = 1 

あなたがこれは各成分が唯一の希望を前提としてい句でにチーズを追加し、= 2

HAVING sum(case when b.vegetables in ('potatoes','cheese') then 1 else 0 end) = 2

する値を変更することができジャガイモとチーズの両方を持っていたレシピを検索したい場合レシピごとに1回リストされます。

あなたが探している成分を知っているので、あなたは動的に平衡数を調整することができます。

+0

私のポストの簡単な例であなたのソリューションをテストしてきました。私は複数の条件のケースで私のポストを編集しました。これ以上の提案があれば、事前に感謝します。 – josei

+0

上記の '' potatoes''と '' 1''がバインドされたパラメータになると、 '' potatoes''は '' potatoes''、 'chicken''、' 'pork''になる可能性があります。 '3'(配列内の3つの項目の数) – xQbert

+0

ありがとうxQbert。私は自分の投稿を編集する。私はあなたのソリューションが気に入っていますが、私はまだ私のケースでそれを動作させることができませんでした。私もGROUP BYの後にこの部分を入れようとしましたが、うまくいきませんでした。私は何が起こっているのか把握しようといくつかのテストをしています。 – josei