2016-05-19 12 views
0
erwartet

Ich habe die folgenden Tabellen:linken JOIN funktioniert nicht wie

store_list

id store 
1 m1 
2 m2 
3 m3 

Shop-Name jeder Speichername für die verkauften Produkte seinen eigenen Tisch haben, mit dem Inhalt wie folgt:

s_m1_sales

id item qty date 
1 x1 5 16-5-2016 
2 x2 6 16-5-2016 
3 x3 1 16-5-2016 

s_m2_sales

id item qty date 
1 x2 3 16-5-2016 
2 x2 3 16-5-2016 
3 x2 5 16-5-2016 

und so weiter für den 3. Laden ...

Und für die letzte Tabelle:

store_items

id item qty cat sub 
10 x1 15 lady slip 
11 x2 10 lady shoe 
12 x3 10 lady shoe 

Jetzt I‘ Ich suche nach einem Bericht, um zu finden, wie viele Artikel mit verkauft wurden in einem bestimmten Datum für eine bestimmte Kategorie (Katze) UND gruppiert nach Kategorie. Ich brauche etwas zu sehen wie folgt aus:

cat sub  M1 M2 M3 date 
lady slip  5 0 0  16-5-2016 
lady shoe  7 11 0  16-5-2016 

Mein PHP-Code, habe ich LINKE als richtig JOIN und Ausgabeergebnis verwendet:

//rest of code 

//Table created 
echo "<table width=90% height=% align=center border=1 cellpadding=3 cellspacing=0>"; 
echo "<tr> 
    <td align=center width=12%><b>Supplier</b></td> 
    <td align=center width=12%><b>Category</b></td> 
    <td align=center width=12%><b>Sub-Category</b></td> 
"; 

foreach($allstore as $store => $value){ 
    echo "<td align=center width=5%><b><font color=green size=+1>".$value."</font></b></td>"; 
} 

//$allstore is an array , by which values taken from user checkbox select 
$allstore = $_POST['store']; 

foreach($allstore as $store => $value){ 

    $query = "SELECT s_{$value}_sales.item_no, 
      store_items.cat, 
      store_items.supplier, 
      store_items.sub, 
      SUM(s_{$value}_sales.qty) AS a1 
     FROM s_{$value}_sales 
     LEFT JOIN store_items ON s_{$value}_sales.item_no = store_items.item_no 
      AND store_items.cat = '".$_POST['cat']."' 
      AND s_{$value}_sales.date BETWEEN '".$_POST['fdate']."' AND '".$_POST['tdate']."' 
      AND store_items.store = '".$value."' 
     GROUP by store_items.sub 
    "; 

    $result= mysql_query($query); 

    while($row = mysql_fetch_assoc($result)) { 
     echo "<tr><td align=center width=12%>{$row['supplier']}</td> 
     <td align=center width=12%>{$row['cat']}</td> 
     <td align=center width=12%>{$row['sub']}</td> 
     <td align=center>".$row['a1']."</td> 
    "; 
    } 
} 
echo "</tr></table>"; 
//rest of code.. 

Wie ich bereits erwähnt, ist die Ausgabe korrekt ist, aber was passiert, dass es Kategorien und Unterkategorien mehrfach wiederholt. Ich will nicht, dass ich Geschäfte und seine Summenmengen in jeder Spalte auflisten will. Wie kann ich es tun ?

Die obige PHP Ausgabe wie folgt:

cat sub M1 M2 M3 
lady slip 5 
lady shoe 7 
lady slip 0 
lady shoe 11 
lady slip 0 
lady shoe 0 
+0

Mit Ihrem aktuellen Schema, müssen Sie eine einzelne Abfrage mit drei linken verbindet, eine an jeder Speicher Tabellenspalte. Sie versuchen, drei separate Abfragen auszuführen, die zu zusätzlichen Zeilen anstelle von zusätzlichen Spalten führen. –

+0

Das funktioniert, wenn Sie nur 3 Geschäftstabellen haben und niemals irgendwelche Geschäfte hinzufügen oder entfernen. Wenn es sich um ein Schulprojekt mit genau 3 Tischen handelt und es sich nicht ändern wird, dann ist dies eine gute Option. Das ist, es sei denn, der Lehrer bewertet die Flexibilität des Codes. Wenn dies ein Problem der realen Welt ist, würde ich stattdessen die Änderung der Tabellenstruktur empfehlen. – ghenghy

+1

Sie verwenden Datenbankcode, der seit 5 Jahren nicht mehr verwendet wird und in aktuellen PHP-Versionen nicht mehr funktionsfähig ist. Alternative Datenbank-APIs wie PDO gibt es seit über einem Jahrzehnt. Beenden Sie die Verwendung von mysql_query() '! – miken32

Antwort

1

Warum für jeden Läden Verkäufe über einen separaten Tisch? Sie sollten in der Lage sein, sie alle in einer einzigen Tabelle mit einer Speicher-ID-Spalte zu kombinieren. Das würde auch helfen, Ihr Problem zu lösen, dass Sie Abfragen in einer Schleife für jeden Speicher machen. Mit diesem Ansatz werden Sie nie in der Lage sein, Daten in einzelnen Zeilen in einzelnen Zeilen zu kompilieren, ohne dass PHP nachbearbeitet werden muss.

id store_id item_id qty date 
1  1  10  5 16-5-2016 
2  1  11  6 16-5-2016 
3  1  12  1 16-5-2016 
4  2  11  3 16-5-2016 
5  2  11  3 16-5-2016 
6  2  11  5 16-5-2016 
... 

Notiere die Zugabe von store_id Feld und das Ersetzen des Elements Feld mit item_id Feld (Sie sollten den entsprechenden Fremdschlüssel hier Referenz):

mir eine alternative store_sales Tabellenstruktur wie diese lassen vorzuschlagen.

, dass Sie Ihre Anfrage an diese zu vereinfachen erlaubt:

SELECT 
    store_list.store AS store, 
    store_items.cat AS cat, 
    store_items.sub AS sub, 
    SUM(store_sales.qty) AS qty 
FROM store_list 
LEFT JOIN store_sales 
    ON store_list.id = store_sales.store_id 
INNER JOIN store_items 
    ON store_sales.item_id = store_items.id 
WHERE store_sales.date BETWEEN ? AND ? 
GROUP BY `store`, `cat`, `sub` 
ORDER BY `store` ASC, `cat` ASC, `sub` ASC 

die eine Ergebnismenge wie geben würde:

store cat sub qty 
m1  lady slip 5 
m1  lady shoe 7 
m2  lady shoe 11 
m3  null null 0 

Es ist trivial diese unter ein mehrdimensionales Array in PHP zu lesen für die Anzeige in dem Format, das Sie für die Seite auswählen.Ich sehe keinen großen Wert darin, Ihre Daten in einen "Pivot-Table" -Typ des von Ihnen gezeigten Formats abzufragen, da dies die Abfrage nur komplexer und weniger performant macht. Dies ist möglich, indem Sie case-Anweisungen in select verwenden, aber ich wollte nicht den Fokus meiner Antwort durcheinander bringen, um primär Ihr Datenbankschema in Ordnung zu bringen.

+0

Danke für deine Zeit, es ist wahr, ich hätte das nicht tun sollen. Also werde ich Tabellen zu einem kombinieren und werde sehen, was passiert. Ich bestätige dir zurück! –

+0

Ich habe es geschafft, das gewünschte Ergebnis basierend auf Ihrem Vorschlag auszugeben. Danke Kumpel +1 –

+0

@AliHamra Froh, zu helfen. –

0

Mikes Antwort enthält einen Fehler, der (wenn er nicht aus der Ergebnismenge beobachtet werden konnte) durch Ausführen von EXPLAIN EXTENDED ... gefolgt von SHOW WARNINGS;

Im Wesentlichen LEFT JOIN x... WHERE x... macht als INNER JOIN x, so Abfrage Mike sollte wie folgt neu geschrieben werden:

SELECT l.store 
    , i.cat 
    , i.sub 
    , SUM(s.qty) qty 
    FROM store_list l 
    LEFT 
    JOIN store_sales s 
    ON s.store_id = l.id 
    AND s.date BETWEEN ? AND ? 
    JOIN store_items i 
    ON i.id = s.item_id 
GROUP 
    BY store 
    , cat 
    , sub; 
+0

Ich weiß nicht, warum Sie einen JOIN basierend auf Ihren Filterkriterien durchführen würden. –

+0

@MikeBrant Meine Anfrage ist ein Duplikat von Ihnen!?!?! – Strawberry

+0

Nein, ist es nicht. Und wenn ja, welchen Wert hätte man, wenn man eine doppelte Antwort hinzufügt? –