2016-12-09 2 views
0

Die folgende Abfrage zeigt eine Liste von Suppen und für jede Suppe eine Liste der Zutaten an.GROUP_CONCAT und LEFT_JOIN - Filtersätze

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

Ich mag die Datensätze filtern, so dass nur die, in denen die Suppe eine bestimmte Zutat hat (zum Beispiel Kartoffeln) angezeigt werden. Etwas wie:

 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 

Diese Abfrage filtert die Datensätze, aber die Liste der Zutaten zeigt nicht mehr alle Zutaten der Suppe, sondern nur die Zutat Kartoffeln anzeigt.

Was ist der beste Weg, dies richtig zu machen?

EDITED:

Mit mehreren Bedingungen - PHP und 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; 
} 
    ... 

Antwort

2

Verwenden FIND_IN_SET, nachdem Sie das Gemüse Liste.

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

Ich habe Ihre Lösung in dem einfachen Beispiel meines Posts getestet und es funktioniert großartig. Allerdings konnte ich mich nicht auf meinen realen Fall beziehen, da dieser mit mehreren Bedingungen filtert. Ich habe meinen Beitrag bearbeitet. Vielen Dank im Voraus, wenn Sie weitere Vorschläge haben. – josei

1

Vielleicht nur eine bedingte Havinglausel?

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 

Wenn Sie nur würde den Wert Rezepte, die hatten beide Kartoffeln und Käse konnte man hinzufügen Käse die in Klausel und ändern werden = 2

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

Dies setzt voraus, jede Zutat finden wollte einmal pro Rezept aufgeführt werden.

Da Sie die Zutaten kennen, die Sie suchen, können Sie die Gleichheitszahl dynamisch anpassen.

+0

Ich habe Ihre Lösung in dem einfachen Beispiel meines Beitrags getestet und es funktioniert auch großartig. Ich habe meinen Post mit mehreren Bedingungen bearbeitet. Vielen Dank im Voraus, wenn Sie weitere Vorschläge haben. – josei

+0

Ich sehe das Problem nicht, wenn "Kartoffeln" und "1" von oben gebundene Parameter werden, die "Kartoffeln" könnten "Kartoffeln", "Huhn", "Schweinefleisch" sein, während der zweite Parameter wäre '3' (die Anzahl der 3 Elemente im Array) – xQbert

+0

Danke xQbert. Ich bearbeite meinen Beitrag. Ich mag deine Lösung, aber ich konnte es immer noch nicht in meinem Fall schaffen. Ich habe auch versucht, diesen Teil der Abfrage nach GROUP BY zu setzen, aber es hat auch nicht funktioniert. Ich mache mehrere Tests, um herauszufinden, was vor sich geht. – josei