2016-07-11 15 views
0

OK, also habe ich einige Stunden mit einem Kumpel von mir diese Abfrage ausarbeiten. Ich habe eine neue "hierarchische" Struktur angenommen, was bedeutet, dass entweder das "Kind" (Geschäft) die Daten ausfüllt und es erfasst oder nicht, so dass das Elternteil (Kette, Ersteller des besagten Geschäftes) die Standardinformation hat was sollte dann ergriffen werden. Jetzt habe ich endlich diese Suchfunktion, um mit dieser Tatsache zu arbeiten. Es funktioniert technisch einwandfrei (obwohl ich denke, es ist nicht sehr effizient, aber SQL ist wirklich nicht mein starker Anzug)MYSQL Anzahl der Suchergebnisse mit group_concat

Nun, das Problem, das ich damit nehme, ist, dass vor dieser hierarchischen Struktur, würde ich 'summe' Die Ergebnisse zeigen, wie viele Übereinstimmungen es gemacht hat. Aber, weil ich jetzt eine ganze Menge von "entweder" oder "Situationen" mache, scheint dieser Teil verwirrt zu sein. Ich habe viele Dinge ausprobiert (DISTINCT COUNT, DISTINCT SUM, COUNT, SUM, THEN 1, THEN +1, THEN -1, etc.)

Also ... ja ... ich bin auf diese wirklich stecken. Die Sache ist, ich brauche den Zähler, um nach der Relevanz zu sortieren.

SELECT stores.ID, store_info.display_name, store_info.address, store_info.phone, 
     IFNULL(GROUP_CONCAT(DISTINCT smallCheese.display_name ORDER BY smallCheese.name), 
       GROUP_CONCAT(DISTINCT bigCheese.display_name ORDER BY bigCheese.name) 
) AS brands, 
     IFNULL(GROUP_CONCAT(DISTINCT 
     CASE WHEN smallCheese.ID IN (3,5,8,11,12,13,14,16,17) 
     THEN smallCheese.display_name 
     ELSE NULL 
     END), 
     (GROUP_CONCAT(DISTINCT 
     CASE WHEN bigCheese.ID IN (3,5,8,11,12,13,14,16,17) 
     THEN bigCheese.display_name 
     ELSE NULL 
     END))     
     ) AS available_brands, 
     COUNT(DISTINCT CASE WHEN smallCheese.ID OR bigCheese.ID IN (3,5,8,11,12,13,14,16,17) 
      THEN 1 
      ELSE 0 
     END) AS available_brands_count 
    FROM stores 
     LEFT JOIN store_info ON (stores.ID = store_info.storeID) 
     LEFT JOIN store_brands ON (stores.ID = store_brands.store) 
     LEFT JOIN chain_brands ON stores.chainID = chain_brands.chain 
     LEFT JOIN brands AS smallCheese ON store_brands.brand = smallCheese.ID 
     LEFT JOIN brands AS bigCheese ON chain_brands.brand = bigCheese.ID 
    WHERE stores.city = 1 
    GROUP BY store_info.storeID 
     ORDER BY `available_brands_count` DESC, store_info.display_name 

Hier ist eine SQL-Geige: http://sqlfiddle.com/#!9/cfe307/1/0

Antwort

1

Ich denke, das funktionieren könnte:

IF (MAX(CASE WHEN smallCheese.ID IN (3,5,8,11,12,13,14,16,17) 
      THEN smallCheese.ID 
      ELSE NULL 
     END) IS NOT NULL, 
    COUNT(DISTINCT 
     CASE WHEN smallCheese.ID IN (3,5,8,11,12,13,14,16,17) 
      THEN smallCheese.ID 
      ELSE NULL 
     END), 
    COUNT(DISTINCT 
     CASE WHEN bigCheese.ID IN (3,5,8,11,12,13,14,16,17) 
      THEN bigCheese.ID 
      ELSE NULL 
     END)) AS available_brands_count 

Sie können nicht nur IFNULL(COUNT(...), COUNT(...)) weil COUNT() kehrt 0 verwenden, wenn es keine Übereinstimmungen gibt. Ich verwende MAX(), um alle IDs zu aggregieren, und wenn keine IDs gefunden werden, wird NULL zurückgegeben.

DEMO

+0

Wirklich nah! Hier ist ein Screenshot der Ergebnisse: http://puu.sh/pYuCr/deb551323d.png - es zählt die 'smallCheese' (Ladenmarken) korrekt, aber es funktioniert nicht an den Kettenmarken (' bigcheese') – NoobishPro

+0

Kannst du Machen Sie eine SQLFiddle mit Beispieldaten? – Barmar

+0

Legen Sie nicht Ihre ganze Datenbank hinein, nur eine Handvoll Einträge zum Testen. – Barmar

0

ich tatsächlich verbessert meine Abfrage viel, mit vielen Dank an die Anfangs von @Barmar bereitgestellt Zählung fix. Weil es schließlich funktioniert hat, habe ich es tatsächlich geschafft, die Abfrage zu verbessern!

SELECT stores.ID, store_info.display_name, store_info.address, store_info.phone, 
     IFNULL(GROUP_CONCAT(DISTINCT smallCheese.display_name ORDER BY smallCheese.name), 
       GROUP_CONCAT(DISTINCT bigCheese.display_name ORDER BY bigCheese.name) 
) AS brands, 
     GROUP_CONCAT(DISTINCT 
     CASE 
     WHEN smallCheese.ID IN (12,11,17) THEN smallCheese.display_name 
     WHEN bigCheese.ID IN(12,11,17) AND smallCheese.ID IS NULL THEN bigCheese.display_name   
     ELSE NULL 
     END ORDER BY bigCheese.name, smallCheese.name) AS available_brands, 

     COUNT(DISTINCT 
     CASE 
     WHEN smallCheese.ID IN (12,11,17) THEN smallCheese.display_name 
     WHEN bigCheese.ID IN(12,11,17) AND smallCheese.ID IS NULL THEN bigCheese.display_name   
     ELSE NULL 
     END) AS available_brands_count 
    FROM stores 
     LEFT JOIN store_info ON (stores.ID = store_info.storeID) 
     LEFT JOIN store_brands ON (stores.ID = store_brands.store) 
     LEFT JOIN chain_brands ON stores.chainID = chain_brands.chain 
     LEFT JOIN brands AS smallCheese ON store_brands.brand = smallCheese.ID 
     LEFT JOIN brands AS bigCheese ON chain_brands.brand = bigCheese.ID 
    WHERE stores.city = 1 
    GROUP BY store_info.storeID 
     HAVING available_brands_count > 0 
     ORDER BY `available_brands_count` DESC, store_info.display_name