我为登录用户创建了一个orders
页面,以便在表中查看他们的订单。我的SELECT语句一开始显示重复的结果,但在尝试修复后,现在每个用户只显示一个订单。
我有两张订单orders
和ordersdetail
的表格。
如何显示所有用户订单,而不是仅显示一个订单或重复订单?
<?php
//CUSTOMER
$user = $_SESSION['email'];
$get_c = "SELECT * FROM customer WHERE email='$user'";
$run_c = $db->query($get_c);
$row_c = $run_c->fetch(PDO::FETCH_BOTH);
$c_id = $row_c['id'];
//ORDERS
$get_o = "SELECT * FROM orders WHERE user_id='$c_id'";
$run_o = $db->query($get_o);
$row_o = $run_o->fetch(PDO::FETCH_BOTH);
$o_id = $row_o['id'];/***/
$o_name = $row_o['name'];
$o_status = $row_o['status'];
$o_userid = $row_o['user_id'];
$o_date = $row_o['date'];
//ORDER DETEAILS
$get_order = "SELECT * FROM ordersdetail WHERE ordersid='$o_id' ";
$run_order = $db->query($get_order);
while($row_o = $run_order->fetch(PDO::FETCH_BOTH)){
$order_id = $row_o['ordersid'];
$o_price = $row_o['price'];
$pro_id = $row_o['productid'];
$o_qty = $row_o['quantity'];
//PRODUCT DETAILS
$get_pro = "SELECT * FROM items WHERE id='$pro_id'";
$run_pro = $db->query($get_pro);
$row_pro = $run_pro->fetch(PDO::FETCH_BOTH);
$pro_image = $row_pro['photo'];
$pro_title = $row_pro['title'];
?>
<tr align="center">
<td><?php echo $o_id;?></td>
<td>
<?php echo $pro_title;?> <b>
<img src="images/<?php echo $pro_image;?>" width="50" height="50" />
</td>
<td><?php echo $o_price;?></td>
<td><?php echo $o_qty;?></td>
</tr>
<?php } ?>
</table>
订单明细表
`ordersdetail` (
`id` int(10) NOT NULL,
`productid` int(11) NOT NULL,
`ordersid` int(11) NOT NULL,
`price` float NOT NULL,
`quantity` int(11) NOT NULL
) ENGINE=InnoDB
订单表
`orders` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`status` tinyint(1) NOT NULL,
`user_id` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB
那里有很多查询,我不相信你需要所有的查询。
要获得给定客户的订单,可以使用联接操作。例如:
SELECT o.id
, o.name
, o.user_id
, o.date
FROM orders o
JOIN customer c
ON c.id = o.user_id
WHERE c.email = ? -- '$user'
ORDER BY o.date DESC, o.id DESC
我会添加一个ORDER BY
子句,使结果更具确定性。如果没有这一点,MySQL可以自由地按其选择的任何顺序返回行。
由于订单可以包含(零?)、一个或多个订单行,因此对ordersdetails
表执行JOIN操作将在返回的每一行上生成"重复"的订单信息。
这里有一个设计选择。任一
1) 我们运行orders查询,并在循环中获取每一行。对于我们提取的每一行,我们从ordersdetails
表中运行一个单独的查询,并为行项目处理这些行。然后再次返回订单循环,获取下一个订单。上面针对外循环的查询,以及类似这样针对内循环的查询。
SELECT l.ordersid
, l.price
, l.productid
, l.quantity
FROM orderdetails l
WHERE l.ordersid = ? -- o.id
另一个大的设计方案是只做一个大查询,比如:
SELECT o.id AS o_id
, o.name AS o_name
, o.user_id AS o_user_id
, o.date AS o_date
, l.id AS d_id
, l.price AS d_price
, l.productid AS d_productid
, l.quantity AS d_quantity
FROM orders o
JOIN customer c
ON c.id = o.user_id
LEFT
JOIN orderdetails l
ON l.ordersid = o.id
WHERE c.email = ? -- '$user'
ORDER BY o.date DESC, o.id DESC, l.id DESC
并处理它。这将需要一些额外的代码。
如果我们提取的行的o_id orderid等于前一行的o_id,我们就知道我们正在处理相同的订单。如果我们在页面上返回这样的结果。。。
order#55
date: 3/25/2016
product price qty status
-------------- -------- --- ----------
1) snugglyfluffy 14.99 12 shipped
2) bitersmiter 99.95 1 fulfillment
3) camelmammal 14,358.00 7 backordered
order#42
date: 12/12/2012
product price qty status
-------------- -------- --- -------
1) hitchhikersguide 12.50 1 shipped
2) towel 4.00 1 shipped
然后,我们需要通过检查订单id(当前行与前一行的订单id)的差异来识别每个订单的"第一行"。当我们获得新订单时,我们会处理订单标题部分,然后处理行项目。在同一订单的下一行,我们只放另一个行项目,重复这一过程,直到我们获得新的订单id。