2017-11-29 1 views
0

Es ist der dritte Tag, ich versuche, eine MySQL-Abfrage zu schreiben. Hat viel gesucht, aber es funktioniert immer noch nicht wie erwartet. Ich werde versuchen, Tabellen, so viel wie möglichMySQL - Join mehrere gemappten Tabellen und Zählen Datensätze mit unterschiedlichen Mapping-Bedingungen

Systems zu vereinfachen hat tkr_restaurants Tabelle:

restaurant_id | restaurant_name 
1    | AA 
2    | BB 
3    | CC 

Jedes Restaurant hat eine zugeordnete Abteilung (tkr_divisions Tabelle):

division_id | restaurant_id | division_name 
1   | 1    | AA-1 
2   | 1    | AA-2 
3   | 2    | BB-1 

Dann Es gibt Mahlzeiten in tkr_meals_to_restaurants_divisions Tabelle, wo jede Mahlzeit zu ganzen Resta zugeordnet werden kann (n) und/oder spezifische Abteilung (en). Wenn das Essen dem Restaurant zugeordnet ist, sollten alle Abteilungen des Restaurants es sehen. Wenn Mahlzeit auf Division (en) abgebildet wird, sollte nur bestimmte Division (en) es sehen.

Ich muss eine Liste der Restaurants und die Anzahl der Mahlzeiten angezeigt abhängig von Benutzerberechtigungen anzeigen.

Beispiel 1: Wenn Benutzerberechtigungen ganze restaurant_id 1 und restaurant_3 zuzugreifen (und keine spezifische Abteilungen), dann sollte Liste sein:

AA | 3 
CC | 0 

(weil Benutzer zugeordnet zugreifen können Mahlzeiten zu Restaurant 1 + alle seine Abteilung, und Restaurant 3 + alle seine Abteilungen (auch wenn Restaurant 3 hat keine Abteilungen/Mahlzeiten abgebildet))

Beispiel 2: wenn Benutzer-Berechtigungen für den Zugriff auf nur 1 division_id, dann sollte Liste sein:

AA | 1 

(da Benutzer nur Zugriff Mahlzeiten Division 1 abgebildet).

Die nächste Abfrage, die ich bekommen konnte ist:

Beispiel 1:

SELECT *, 
    (SELECT COUNT(DISTINCT meal_id) 
    FROM 
     tkr_meals_to_restaurants_divisions 
    WHERE 
tkr_meals_to_restaurants_divisions.mapped_restaurant_id=tkr_restaurants.restaurant_id 
    OR tkr_meals_to_restaurants_divisions.mapped_division_id=tkr_divisions.division_id)AS total_meals 
    FROM 
     tkr_restaurants 
    LEFT JOIN 
     tkr_divisions 
     ON tkr_restaurants.restaurant_id=tkr_divisions.restaurant_id 
    WHERE 
     tkr_restaurants.restaurant_id IN (1, 3) 
     OR tkr_restaurants.restaurant_id IN (
      SELECT restaurant_id 
      FROM tkr_divisions 
      WHERE division_id IN (NULL) 
     ) 
    GROUP BY 
     tkr_restaurants.restaurant_id 
    ORDER BY 
     tkr_restaurants.restaurant_name 

jedoch Ergebnis war:

AA | 2 
CC | 0 

Ich glaube, ich bin stark zu verkomplizieren diese Abfrage, aber all die einfacheren Abfragen, die ich schrieb, ergaben noch ungenauere Ergebnisse.

+0

Warum in Beispiel 2 die Mahlzeit mit 'meal_id' 2 ist nicht erlaubt? Es wird der Division 1 zugeordnet. – Marcus

+0

Wenn Sie sich auf Beispiel 2 mit der Angabe "AA | 1" beziehen, beachten Sie, dass die Nummer nicht die ID anzeigt, sondern die Gesamtzahl der einer bestimmten Division zugewiesenen Mahlzeiten (und die Gesamtzahl der Mahlzeiten in der Division) 1 ist 1) –

Antwort

1

Was ist mit dieser Abfrage:

SELECT 
FROM tkr_restaurants AS a 
JOIN tkr_divisions AS b 
ON a.restaurant_id = b.restaurant_id 
LEFT OUTER JOIN tkr_meals_to_restaurants_divisions AS c 
ON (c.mapped_restaurant_id = a.restaurant_id OR c.mapped_division_id = b.division_id) 

als Basis vier Ihre weitere Arbeit. Es kombiniert alle Informationen in einer Tabelle. Wenn Sie z.B.dies:

WHERE a.restaurant_id IN (1, 3) 

das Ergebnis wird sein,

| restaurant_id | restaurant_name | division_id | restaurant_id | division_name | meal_id | mapped_restaurant_id | mapped_division_id | 
|---------------|-----------------|-------------|---------------|---------------|---------|----------------------|--------------------| 
|    1 |    AA |   1 |    1 |   AA-1 |  1 |     1 |    (null) | 
|    1 |    AA |   2 |    1 |   AA-2 |  1 |     1 |    (null) | 
|    1 |    AA |   1 |    1 |   AA-1 |  2 |    (null) |     1 | 
|    1 |    AA |   2 |    1 |   AA-2 |  3 |    (null) |     2 | 

zählen nur die unterschiedlichen Mahlzeit ids mit COUNT(DISTINCT c.meal_id) und nehmen Sie das Restaurant Namen AA: 3 für Ihr Beispiel 2

Ich benutzte einen sqlfiddle zu bekommen: http://sqlfiddle.com/#!9/fa2b78/18/0

[EDIT]

ändern JOIN tkr_divisions AS b-LEFT OUTER JOIN tkr_divisions AS b

ändern SELECT *-SELECT a.restaurant_name, COUNT(DISTINCT c.meal_id)

ein GROUP BY a.restaurant_name am Ende hinzufügen.

Aktualisieren Sie die SQL Fiddle (neue Verbindung)

+0

Danke, ich werde es jetzt mit einigen weiteren Beispielen auf meinem System debuggen. –

+0

Leider funktioniert es nur teilweise. Wenn ich den Code für das erste Beispiel verwende, werden die Mahlzeiten korrekt gezählt, aber das Restaurant mit der ID 3 wird nicht angezeigt. Wenn in der Abfrage eine Restaurant ID mit 3 verwendet wurde, sollte diese ebenfalls angezeigt werden (auch wenn keine Aufteilung/Verpflegung zugewiesen wurde). Das Ergebnis sollte also 'AA | sein 3 CC | 0' –

+0

Warum aber Restaurant 'CC' anzeigen, wenn' BB' auch 0 ist? – Marcus

Verwandte Themen