我有一个贯穿所有订单历史的脚本。打印结果需要几分钟,但是我注意到我执行了几个非常相似的sql语句,我想知道您是否可以对现有的sql结果执行另一个查询。
例如:
-- first SQL request
SELECT * FROM orders
WHERE status = 'shipped'
然后,在foreach循环中,我想从这个结果中找到信息。我天真的方法是执行这三个查询。请注意与上述查询的相似性。
-- grabs customer's LTD sales
SELECT SUM(total) FROM orders
WHERE user = :user
AND status = 'shipped'
-- grabs number of orders customer has made
SELECT COUNT(*) FROM orders
WHERE user = :user
AND status = 'shipped'
AND total != 0
-- grabs number of giveaways user has won
SELECT COUNT(*) FROM orders
WHERE user = :user
AND status = 'shipped'
AND total = 0
当我搜索的结果是第一个查询的子集时,我会多次查询同一个表。我希望在不执行更多sql调用的情况下从第一个查询中获取信息。一些伪代码:
$stmt1 = $db->prepare("
SELECT * FROM orders
WHERE status = 'shipped'
");
$stmt1->execute();
foreach($stmt1 as $var) {
$username = $var['username'];
$stmt2 = $stmt1->workOn("
SELECT SUM(total) FROM this
WHERE user = :user
");
$stmt2->execute(array(
':user' => $username
));
$lifesales = $stmt2->fetchColumn();
$stmt3 = $stmt1->workOn("
SELECT COUNT(*) FROM this
WHERE user = :user
AND total != 0
");
$stmt3->execute(array(
':user' => $username
));
$totalorders = $stmt3->fetchColumn();
$stmt4 = $stmt1->workOn("
SELECT COUNT(*) FROM this
WHERE user = :user
AND total = 0
");
$stmt4->execute(array(
':user' => $username
));
$totalgaws = $stmt4->fetchColumn();
echo "Username: ".$username;
echo "<br/>Lifetime Sales: ".$lifesales;
echo "<br/>Total Orders: ".$totalorders;
echo "<br/>Total Giveaways: ".$totalgaws;
echo "<br/><br/>";
}
这样的事情可能吗?速度快吗?我现有的方法是缓慢和丑陋的,我想一个更快的方法来做这件事。
2条答案
按热度按时间rt4zxlrg1#
我们可以对表进行一次遍历,以获得所有用户的所有三个聚合:
大套的话会很贵的。但是,如果我们对所有订单、所有用户都需要这样做,那么这可能比单独进行相关子查询要快。
前导列为的索引
user
将允许mysql使用GROUP BY
操作。包括status
以及total
索引中的列将允许完全通过索引满足查询(等式 predicate 在status
列,我们还可以尝试使用status
作为第一列,后面是user
列,然后后跟total
.如果我们只对一小部分用户需要这个结果,例如,我们只从第一个查询中提取前10行,那么运行一个单独的查询可能会更快。我们只需要合并条件
WHERE s.user = :user
进入查询,如在原始代码中。但是只运行一个查询,而不是三个单独的查询。我们可以将其与第一个查询结合起来,方法是将其放入一个内联视图,将其 Package 在paren中并放入
FROM
子句作为行源我不太清楚那个名为“先前”销售的专栏。。。这是返回所有已发货订单,而不考虑比较任何日期(订单日期、履行日期、装运日期),我们通常会将其与“之前”的含义联系起来。
后续行动
注意到问题已被修改,删除条件“
status = 'shipped'
“从用户所有订单的计数。。。我会注意到我们可以从
WHERE
条件聚合中的子句。并不是所有这些结果都是op需要的,但作为一个示范。。。
9gm1akwq2#
一旦结果从数据库返回,就不能在其上运行sql。但是,您可以将它们存储在临时表中,以便重用它们。
https://dev.mysql.com/doc/refman/8.0/en/create-temporary-table.htmlhttpshttp://dev.mysql.com/doc/refman/8.0/en/create-table-select。htmlhttps://dev.mysql.com/doc/refman/8.0/en/insert-select.html
您需要创建一个临时表,并插入select语句中的所有数据,然后可以对该表运行查询。不知道这对你是否有帮助。
对于您的特殊情况,您可以执行以下操作:
但是,您必须进行一些额外的求和,以获得第二个查询的结果,该查询将为您提供每个用户的求和,因为它们将被分为两个不同的组,具有不同的is\u total\u零值。