使用 LEFT JOIN 未按预期工作
Using LEFT JOIN not working as expected
我有以下 tables :
store_list
id store
1 m1
2 m2
3 m3
包含商店名称,每个商店名称都有自己的 table 售出商品如下:
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
第 3 家商店依此类推...
最后的 Table :
store_items
id item qty cat sub
10 x1 15 lady slip
11 x2 10 lady shoe
12 x3 10 lady shoe
现在我正在寻找一份报告,以查找特定类别(类别)在特定日期内售出的商品数量,并且按类别分组。我也需要这样的东西 :
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
为什么每个商店的销售额都有单独的 table?您应该能够轻松地将它们全部组合成一个带有商店 ID 列的 table。这也将有助于解决您的问题,即您正在为每个商店循环查询。使用这种方法,如果不在 PHP.
中进行一些 post 处理,您将永远无法将跨商店的数据编译成单行。
让我提出一个替代 store_sales table 结构,如下所示:
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_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 中的多维数组中读取此内容很简单,以便以您为页面选择的任何格式显示。我认为尝试将您的数据查询为您显示的 "pivot table" 类型的格式没有多大价值,因为这只会使查询更复杂且性能更低。这可以在 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;
我有以下 tables :
store_list
id store
1 m1
2 m2
3 m3
包含商店名称,每个商店名称都有自己的 table 售出商品如下:
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
第 3 家商店依此类推...
最后的 Table :
store_items
id item qty cat sub
10 x1 15 lady slip
11 x2 10 lady shoe
12 x3 10 lady shoe
现在我正在寻找一份报告,以查找特定类别(类别)在特定日期内售出的商品数量,并且按类别分组。我也需要这样的东西 :
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
为什么每个商店的销售额都有单独的 table?您应该能够轻松地将它们全部组合成一个带有商店 ID 列的 table。这也将有助于解决您的问题,即您正在为每个商店循环查询。使用这种方法,如果不在 PHP.
中进行一些 post 处理,您将永远无法将跨商店的数据编译成单行。让我提出一个替代 store_sales table 结构,如下所示:
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_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 中的多维数组中读取此内容很简单,以便以您为页面选择的任何格式显示。我认为尝试将您的数据查询为您显示的 "pivot table" 类型的格式没有多大价值,因为这只会使查询更复杂且性能更低。这可以在 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;