假设我在MySQL数据库中有两个表。第一个名为products
,第二个名为sales
。
让我为products
表格保留三个不同的条目......
+-------+-----------------+-----------+--------+
|id | productname | quantity | uom |
+-------+-----------------+-----------+--------+
|1 | water bottle | 20 | piece |
|2 | cable | 200 | meter |
|3 | soap | 1 | piece |
+-------+-----------------+-----------+--------+
此外,我在sales
表格中输入的内容很少 -
+-------+---------------------+-----------+--------+-----------+
|id | date | quantity | uom | productid |
+-------+---------------------+-----------+--------+-----------+
|1 | 2013-06-21 09:34:00 | 20 | meter | 2 |
|2 | 2013-06-21 10:35:00 | 100 | meter | 2 |
|3 | 2013-06-21 11:36:00 | 1 | piece | 3 |
+-------+---------------------+-----------+--------+-----------+
上面的sales
表productid
是foreign key
。每个销售条目都保留productid
。现在,如何使用左表中的单个条目和基于外键的右表中的多个条目创建报告。
让我创建一个报告的模型 -
+-----------------+-----------+--------+---------------------+-----------+
| productname | quantity | uom | date | quantity |
+-----------------+-----------+--------+---------------------+-----------+
| cable | 200 | meter | 2013-06-21 09:34:00 | 20 |
| | | | 2013-06-21 10:35:00 | 100 |
| soap | 1 | piece | 2013-06-21 11:36:00 | 1 |
| water bottle | 20 | piece | | |
+-----------------+-----------+--------+---------------------+-----------+
是否可以使用MySQL创建基于外键的上述报告?
答案 0 :(得分:1)
更新 从结果集中呈现报表的客户端代码不是为RDBMS做的工作。
使用JOIN
生成结果集,然后根据您的选择使用客户端脚本语言构建报表的布局。
如果是php,您可能会发现在查询中使用GROUP_CONCAT()
并在php端使用explode()
非常方便。
SELECT p.productname,
p.quantity total_quantity,
p.uom,
GROUP_CONCAT(CONCAT(COALESCE(s.date, ''),'|',COALESCE(s.quantity, '')) ORDER BY s.date) details
FROM products p LEFT JOIN sales s
ON p.id = s.productid
GROUP BY s.productid, p.productname, p.quantity, p.uom
ORDER BY p.productname
示例输出:
| PRODUCTNAME | TOTAL_QUANTITY | UOM | DETAILS | ------------------------------------------------------------------------------------------ | cable | 200 | meter | 2013-06-21 09:34:00|20,2013-06-21 10:35:00|100 | | soap | 1 | piece | 2013-06-21 11:36:00|1 | | water bottle | 20 | piece | | |
这是 SQLFiddle 演示。
使用PDO的php代码可能看起来像
<?php
$db = new PDO('mysql:host=localhost;dbname=database_name', 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$sql = "SELECT p.productname,
p.quantity total_quantity,
p.uom,
GROUP_CONCAT(CONCAT(COALESCE(s.date, ''),'|',COALESCE(s.quantity, '')) ORDER BY s.date) details
FROM products p LEFT JOIN sales s
ON p.id = s.productid
GROUP BY s.productid, p.productname, p.quantity, p.uom
ORDER BY p.productname";
$query = $db->prepare($sql);
$query->execute();
$rows = $query->fetchall(PDO::FETCH_ASSOC);
$query = null;
$db = null;
?>
<table>
<thead>
<tr>
<th>Product Name</th>
<th>Total quantity</th>
<th>UOM</th>
<th>Date</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<?php
foreach($rows as $row) {
echo "<tr>
<td>{$row['productname']}</td>
<td>{$row['total_quantity']}</td>
<td>{$row['uom']}</td>";
$details = explode(',', $row['details']);
$i = 1;
foreach($details as $detail) {
list($date, $quantity) = explode('|', $detail);
if ($i > 1) {
echo "<td></td><td></td><td></td>";
}
echo "<td>$date</td>
<td>$quantity</td></tr>";
$i++;
}
}
?>
</tbody>
</table>
哪会产生结果
Product Name Total quantity UOM Date Quantity cable 120 meter 2013-06-21 09:34:00 20 2013-06-21 10:35:00 100 soap 1 piece 2013-06-21 11:36:00 1 water bottle 20 piece
答案 1 :(得分:0)
您可以在查询结束时使用join和group by查询,但据我所知,MySQL查询的回复不会返回行中的空字段。
select products.productname , sales.quantity , sales.uom , sales.date , sales.quantity from sales, products where sales.product.id = products.product.id group by products.productname , sales.date
如您所见,查询的答案将具有重复的productname,但在其他列中具有不同的值。