比嵌套SELECT语句更好的方法SQL

时间:2019-07-10 13:31:44

标签: php sql

我想更新购物车表中的产品。如果用户选择了一个选项,则产品ID将更改为具有所需选项的产品(每个产品都包含在产品表中,每个ID都有不同的变体)。

我提出了一个嵌套请求,以选择用户想要从购物车表中进行更改的产品,然后在产品表中找到该产品,获取参考代码,然后查找具有相同参考代码的同级产品,并保留同类产品。与所需的变体。最后,我更新购物车表。

有更好的方法吗?如果是,它将更快或更安全,还是更容易阅读?

谢谢。

$result = $conn->query("SELECT * FROM tbl_product
   WHERE code=(SELECT code FROM tbl_product
    WHERE id=(SELECT product_id FROM tbl_cart
      WHERE id='".$_POST['cartId']."' AND member_id=$memberId))
        AND option_1='".$_POST['option']."'");
$product = $result->fetch_assoc();


$query = "UPDATE tbl_cart SET product_id = ?, quantity = ? WHERE id = ? AND member_id = ?";

$stmt = $conn->prepare($query);
$stmt->bind_param('iiii', $product['id'], $_POST["newQuantity"], $_POST["cartId"], $memberId);
$stmt->execute();
$stmt->close();

餐桌产品

+----+------------+--------+----------+--------+
| id |    name    |  code  | option_1 | price  |
+----+------------+--------+----------+--------+
|  2 | Hard Drive | USB2   |          | 199.90 |
|  3 | Watch      | Wear   |          | 150.50 |
|  6 | Camera     | 3DcA   | L        | 109.99 |
|  7 | Camera     | 3DcA   | XL       | 119.99 |
|  8 | Camera     | 3DcA   | XXL      | 129.99 |
|  9 | Camera     | 3DcA   | M        |  99.99 |
+----+------------+--------+----------+--------+

餐车:

+-----+------------+----------+-----------+
| id  | product_id | quantity | member_id |
+-----+------------+----------+-----------+
| 176 |          6 |        1 |         1 |
+-----+------------+----------+-----------+

我添加了两个表,以向您展示它们的制作方式。 也许我在构建它们的方式上犯了一个错误。 这是创建父/子结构的好方法吗?

2 个答案:

答案 0 :(得分:0)

首先,该查询容易受到SQL注入的攻击。您应该像对SELECT使用准备好的语句那样使用UPDATE

从执行的角度来看,您的SQL引擎很可能正在使用Semi-Joins优化此查询。该链接说明了半联接优化如何在MySQL中工作。因此,您 可能 不会对性能造成影响。

如果product_id已经在tbl_products中,那么您的第一个子查询似乎也是多余的,为什么还要在同一表中为code进行子查询?

也就是说,从可读性的角度来看,我将从一开始就使用JOIN。没有看到您的架构,我不能100%确定,但是类似这样的查询可能接近查询的Join版本。

$query = "SELECT products.* FROM tbl_cart cart
    JOIN tbl_product products ON products.id = cart.product_id
    WHERE cart.id = ?
    AND cart.member_id = ?
    AND products.option_1 = ?";

$stmt = $conn->prepare($query);
$stmt->bind_param($_POST['cartId'], $memberId, $_POST['option']);
$stmt->execute();
$product = $stmt->fetch_assoc();

请注意,以上假设使用MySQL或MariaDB。

答案 1 :(得分:0)

考虑MySQL的UPDATE...JOIN语法,并避免第一个SELECT查询调用。下面删除了多余的 product_id 分配。另外, option_1 JOIN子句中处理,并假定为字符串值。

$query = "UPDATE tbl_cart c
          INNER JOIN tbl_product p
          SET c.product_id = p.id,
              c.quantity = ?,
          WHERE c.id = ? 
            AND c.member_id = ?
            AND p.option_1 = ?";

$stmt = $conn->prepare($query);
$stmt->bind_param('iiis', $_POST["newQuantity"], $_POST["cartId"], 
                          $memberId, $_POST['option']);
$stmt->execute();
$stmt->close();

Db Fiddle