我想更好地优化我的代码。我希望有一个查询允许别名具有自己的限制,并且还包含无限制的结果。
目前我正在使用两个这样的查询:
// ALL TIME //
$mikep = mysqli_query($link, "SELECT tasks.EID, reports.how_did_gig_go FROM tasks INNER JOIN reports ON tasks.EID=reports.eid WHERE `priority` IS NOT NULL AND `partners_name` IS NOT NULL AND mike IS NOT NULL GROUP BY EID ORDER BY tasks.show_date DESC;");
$num_rows_mikep = mysqli_num_rows($mikep);
$rating_sum_mikep = 0;
while ($row = mysqli_fetch_assoc($mikep)) {
$rating_mikep = $row['how_did_gig_go'];
$rating_sum_mikep += $rating_mikep;
}
$average_mikep = $rating_sum_mikep/$num_rows_mikep;
// AND NOW WITH A LIMIT 10 //
$mikep_limit = mysqli_query($link, "SELECT tasks.EID, reports.how_did_gig_go FROM tasks INNER JOIN reports ON tasks.EID=reports.eid WHERE `priority` IS NOT NULL AND `partners_name` IS NOT NULL AND mike IS NOT NULL GROUP BY EID ORDER BY tasks.show_date DESC LIMIT 10;");
$num_rows_mikep_limit = mysqli_num_rows($mikep_limit);
$rating_sum_mikep_limit = 0;
while ($row = mysqli_fetch_assoc($mikep_limit)) {
$rating_mikep_limit = $row['how_did_gig_go'];
$rating_sum_mikep_limit += $rating_mikep_limit;
}
$average_mikep_limit = $rating_sum_mikep_limit/$num_rows_mikep_limit;
这使我能够显示过去10次评论的历史平均值和平均值。我真的有必要设置两个查询吗?
另外,我知道我可以在查询中得到总和,但并非所有值都是数字,所以我实际上已经用PHP转换它们,但是为了尝试简化显示的内容而省略了代码在代码中。
答案 0 :(得分:1)
过去10次评论的历史平均值和平均值
在最佳情况下,您的列how_did_gig_go
是100%数字的,像这样的单个查询可以这样工作:
SELECT
AVG(how_did_gig_go) AS avg_how_did_gig_go
, SUM(CASE
WHEN rn <= 10 THEN how_did_gig_go
ELSE 0
END) / 10 AS latest10_avg
FROM (
SELECT
@num + 1 AS rn
, tasks.show_date
, reports.how_did_gig_go
FROM tasks
INNER JOIN reports ON tasks.EID = reports.eid
CROSS JOIN ( SELECT @num := 0 AS n ) AS v
WHERE priority IS NOT NULL
AND partners_name IS NOT NULL
AND mike IS NOT NULL
ORDER BY tasks.show_date DESC
) AS d
但;除非所有“数字”实际上都是数字,否则你注定要从服务器发送每一行以供php处理,除非你能以某种方式清理MySQL中的数据。
如果您为php设置了一个仅使用整个列表中前10位的方法,则可能会避免两次发送所有数据。在PHP中可能有这样做的方法。
如果您希望在SQL中提供帮助,那么可能有2列会有所帮助,这会减少表扫描的数量。
SELECT
EID
, how_did_gig_go
, CASE
WHEN rn <= 10 THEN how_did_gig_go
ELSE 0
END AS latest10_how_did_gig_go
FROM (
SELECT
@num + 1 AS rn
, tasks.EID
, reports.how_did_gig_go
FROM tasks
INNER JOIN reports ON tasks.EID = reports.eid
CROSS JOIN ( SELECT @num := 0 AS n ) AS v
WHERE priority IS NOT NULL
AND partners_name IS NOT NULL
AND mike IS NOT NULL
ORDER BY tasks.show_date DESC
) AS d
将来(MySQL 8.x)ROW_NUMBER() OVER(order by tasks.show_date DESC)
将是比之前显示的“滚动你自己的”行编号(using @num+1
)更好的方法。