执行此 SQL 查询的更快方法
Faster way of performing this SQL query
我有一个很大的 SQL table 存储用户添加到他们的个人资料中的附加项目 ID 和他们给它的评级。问题是,我需要快速计算一个项目被添加了多少次,还需要获得它给出的总评分。有时,评级可能为空,也可能不为空,具体取决于用户是否为该项目留下了评级。 table 看起来像这样
Item_Feedback_ID (Pri, AI) Item ID Item Rating User_ID_Added
1 5 Null 4
2 5 8 5
3 6 9 9
我需要为存在的每个唯一项目 ID 执行此操作(我已经有一个 table 存储唯一项目 ID)。我现在正在做的是:
PSEUDO PHP CODE:
$result = the result of: "SELECT item_id FROM items";
foreach ($item_id in $result) {
$sql = "SELECT COUNT(item_id) as sum, SUM(`Item Rating`) as total_rating FROM
item_feedback WHERE item_id = $item_id";
//Run that sql statement in PHP and parse it and save in an array
}
有没有更有效的方法?似乎我浪费了很多时间,因为 COUNT 已经扫描了所有列,我必须再次为 x 个项目 ID 执行此操作。
您应该能够使用可选数据的子查询来完成这一查询。我正在为额外数据使用 LEFT JOIN,这样仍然会返回没有该数据的项目。子查询的原因是因为您正在使用 COUNT
。如果没有子查询,那将计算所有记录,而不仅仅是有反馈的记录。
SELECT
items.item_id,
feedback.sum,
feedback.total_rating
FROM items
LEFT JOIN(
SELECT
item_id,
COUNT(item_id) as sum,
SUM(`Item Rating`) as total_rating
FROM item_feedback
GROUP BY item_id
) AS feedback ON feedback.item_id = items.item_id
$sql = "SELECT ifnull(t.count, 0) as count,
ifnull(t.total_rating, 0) total_rating,
a.item_id
FROM items a
left join (SELECT COUNT(item_id) as count,
SUM(`Item Rating`) as total_rating,
b.item_id
from item_feedback b
group by b.item_id) t on t.item_id = a.item_id " ;
我不是 PHP 方面的专家,但也许您可以将数据放入临时 table 中,然后循环遍历它。也许您的 SQL 脚本会像这样。
INSERT INTO TempTable
SELECT
COUNT(item_id) as sum,
SUM(`Item Rating`) as total_rating
FROM item_feedback
GROUP BY item_id
然后按 item_id
遍历您的 TempTable
如果您不需要为每个项目一行,那么只需查询 item_feedback 就足够了,使用 SQL CASE
语句将帮助您解决问题嗯:
select
item_id,
count(*) as item_added_count,
sum(case when [item rating] is not null then 1 else 0 end) as rating_count
from item_feedback
group by item_id
如果您确实需要为每个项目占一行,并且希望在该项目从未添加到 item_feedback table 时显示 0,则使用 LEFT OUTER JOIN
和项目 table:
select
i.item_id,
sum(case when f.item_id is not null then 1 else 0 end) as item_added_count,
sum(case when f.[item rating] is not null then 1 else 0 end) as rating_count
from items i
left outer join item_feedback f on f.item_id = i.item_id
group by i.item_id
我有一个很大的 SQL table 存储用户添加到他们的个人资料中的附加项目 ID 和他们给它的评级。问题是,我需要快速计算一个项目被添加了多少次,还需要获得它给出的总评分。有时,评级可能为空,也可能不为空,具体取决于用户是否为该项目留下了评级。 table 看起来像这样
Item_Feedback_ID (Pri, AI) Item ID Item Rating User_ID_Added
1 5 Null 4
2 5 8 5
3 6 9 9
我需要为存在的每个唯一项目 ID 执行此操作(我已经有一个 table 存储唯一项目 ID)。我现在正在做的是:
PSEUDO PHP CODE:
$result = the result of: "SELECT item_id FROM items";
foreach ($item_id in $result) {
$sql = "SELECT COUNT(item_id) as sum, SUM(`Item Rating`) as total_rating FROM
item_feedback WHERE item_id = $item_id";
//Run that sql statement in PHP and parse it and save in an array
}
有没有更有效的方法?似乎我浪费了很多时间,因为 COUNT 已经扫描了所有列,我必须再次为 x 个项目 ID 执行此操作。
您应该能够使用可选数据的子查询来完成这一查询。我正在为额外数据使用 LEFT JOIN,这样仍然会返回没有该数据的项目。子查询的原因是因为您正在使用 COUNT
。如果没有子查询,那将计算所有记录,而不仅仅是有反馈的记录。
SELECT
items.item_id,
feedback.sum,
feedback.total_rating
FROM items
LEFT JOIN(
SELECT
item_id,
COUNT(item_id) as sum,
SUM(`Item Rating`) as total_rating
FROM item_feedback
GROUP BY item_id
) AS feedback ON feedback.item_id = items.item_id
$sql = "SELECT ifnull(t.count, 0) as count,
ifnull(t.total_rating, 0) total_rating,
a.item_id
FROM items a
left join (SELECT COUNT(item_id) as count,
SUM(`Item Rating`) as total_rating,
b.item_id
from item_feedback b
group by b.item_id) t on t.item_id = a.item_id " ;
我不是 PHP 方面的专家,但也许您可以将数据放入临时 table 中,然后循环遍历它。也许您的 SQL 脚本会像这样。
INSERT INTO TempTable
SELECT
COUNT(item_id) as sum,
SUM(`Item Rating`) as total_rating
FROM item_feedback
GROUP BY item_id
然后按 item_id
遍历您的 TempTable如果您不需要为每个项目一行,那么只需查询 item_feedback 就足够了,使用 SQL CASE
语句将帮助您解决问题嗯:
select
item_id,
count(*) as item_added_count,
sum(case when [item rating] is not null then 1 else 0 end) as rating_count
from item_feedback
group by item_id
如果您确实需要为每个项目占一行,并且希望在该项目从未添加到 item_feedback table 时显示 0,则使用 LEFT OUTER JOIN
和项目 table:
select
i.item_id,
sum(case when f.item_id is not null then 1 else 0 end) as item_added_count,
sum(case when f.[item rating] is not null then 1 else 0 end) as rating_count
from items i
left outer join item_feedback f on f.item_id = i.item_id
group by i.item_id