[英]Using LEFT JOIN not working as expected
我有以下表格:
store_list
id store
1 m1
2 m2
3 m3
包含商店名稱,每個商店名稱通過它來擁有自己的已售商品表,如下所示:
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
對第三家商店等等
對於最終表:
store_items
id item qty cat sub
10 x1 15 lady slip
11 x2 10 lady shoe
12 x3 10 lady shoe
現在,我正在尋找一份報告,以查找特定日期(類別)和GROUP BY BY類別在特定日期內售出的商品數量。 我也需要這樣的東西:
cat sub M1 M2 M3 date
lady slip 5 0 0 16-5-2016
lady shoe 7 11 0 16-5-2016
我的PHP代碼中,我使用了LEFT JOIN並正確輸出了結果:
//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..
正如我前面提到的,輸出是正確的,但是會發生多次循環類別和子類別的情況。 我不希望在每一列中列出存儲及其總數量。 我該怎么做 ?
上面的PHP輸出如下:
cat sub M1 M2 M3
lady slip 5
lady shoe 7
lady slip 0
lady shoe 11
lady slip 0
lady shoe 0
為什么每個商店的銷售額都有單獨的表格? 您應該可以輕松地將它們全部合並到帶有store id列的單個表中。 這也將有助於解決您的問題,即您正在循環查詢每個商店。 使用這種方法,如果不進行PHP中的一些后處理,您將永遠無法將跨商店的數據編譯成單行。
讓我提出一個替代的store_sales表結構,如下所示:
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
...
請注意,添加了store_id字段,並將item字段替換為item_id字段(您應在此處引用適當的外鍵)。
這樣可以簡化查詢:
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
那將得到如下結果集:
store cat sub qty
m1 lady slip 5
m1 lady shoe 7
m2 lady shoe 11
m3 null null 0
在PHP中讀取此多維數組以便以您為頁面選擇的任何格式顯示都是很簡單的。 在嘗試將您的數據查詢為您顯示的“數據透視表”類型時,我看不出太多價值,因為這只會使查詢更復雜且性能更低。 可以在select中使用case語句來做到這一點,但是我不想讓我的答案混亂,主要是為了使數據庫模式有序。
Mike的答案包含一個錯誤,如果執行EXPLAIN EXTENDED ...,然后顯示SHOW WARNINGS,則會顯示該錯誤(如果無法從結果集中觀察到)。
本質上, LEFT JOIN x... WHERE x...
呈現為INNER JOIN x
,因此Mike的查詢應按以下方式重寫:
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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.