优化 SQL 请求

Optimize SQL request

我想优化我的 SQL 请求,因为它看起来很糟糕而且有点慢。

我有两个 tables :

订单

order_id | order_number | order_date | customer_id | commercial_id | product_id

客户

customer_id | customer_name

当商业为客户下订单时,我的 ORDERS table 中有这样的条目:

1 | 6750 | 2021-08-09 | 854 | 64 | 12

1 | 6750 | 2021-08-09 | 854 | 64 | 32

1 | 6750 | 2021-08-09 | 854 | 64 | 41

我正在制作一个数组来显示商业订单列表:

order_number, order_date, customer_name

这里是我的代码

//Getting all orders of the commercial

$req = $bdd->prepare("SELECT distinct order_number, order_date FROM orders WHERE commercial_id = :commercial_id ORDER BY order_date DESC");
$req->BindParam(':commercial_id',$commercial_id);   
$req->execute();
$distinct_orders = $req->fetchAll(PDO::FETCH_ASSOC);

$orders = [];

//Looping all orders number and get the customer name

foreach($distinct_orders as $distinct_order){
    $req = $bdd->prepare("
        SELECT O.*, C.customer_name
        FROM orders O
        LEFT JOIN customers C
        ON O.customer_id = C.customer_id
        WHERE O.order_number = :order_number
    ");
    $req->BindParam(':order_number',$distinct_order['order_number']);   
    $req->execute();
    $order = $req->fetch(PDO::FETCH_ASSOC);
    
    $orders[$order['order_number']] = [
        'order_number'      => $order['order_number'],
        'order_date'        => $order['order_date'],
        'customer_name'     => $order['customer_name']
    ];
}

我知道这很糟糕,我相信有一种方法可以让加入变得更容易。

只需在第二个查询中使用 commercial_id。像这样:

$orders = [];

$req = $bdd->prepare("
        SELECT O.*, C.customer_name
        FROM orders O
        LEFT JOIN customers C
        ON O.customer_id = C.customer_id
        WHERE O.commercial_id = :commercial_id
");
$req->BindParam(':commercial_id',$commercial_id);   
$req->execute();
$order = $req->fetch(PDO::FETCH_ASSOC);
    
//Looping all orders number and get the customer name
foreach($order as $order){
    $orders[$order['order_number']] = [
        'order_number'      => $order['order_number'],
        'order_date'        => $order['order_date'],
        'customer_name'     => $order['customer_name']
    ];
}

您可以将其合并为一个查询:

SELECT O.*, C.customer_name
FROM orders O LEFT JOIN
     customers C
     ON O.customer_id = C.customer_id
WHERE O.order_number IN (SELECT o2
                         FROM orders o2
                         WHERE o2.commercial_id = :commercial_id
                         ORDER BY order_date DESC
                        );

对于此查询,您需要 orders(commercial_id, order_date desc) 上的索引。

你的问题没有具体说明你的数据结构。可能有更简单的方式来表达这一点。例如,order_number 是唯一的吗?

这是有效的。

SELECT DISTINCT ORD.order_number, ORD.order_date, CUS.customer_id, CUS.customer_name
FROM orders ORD
LEFT JOIN customers CUS
ON ORD.customer_id = CUS.customer_id
WHERE ORD.commercial_id = :commercial_id
ORDER BY ORD.order_number DESC

谢谢大家!