[英]SQL: Sum the results of a query by group
幾天前我剛剛開始學習 SQL,我正在研究一些基本的例子。 在這個例子中,我想找到我的朋友和隊友喜歡的訓練(基於我有多少朋友喜歡訓練,有多少朋友完成了訓練,以及我的朋友對訓練的平均評分)。 到目前為止,我使用子查詢為每次訓練的每種類型的加權值獲取加權值。 我想對每個訓練的加權值求和,給每個訓練一個總數,然后按總數對訓練列表進行排序,並從中選擇前幾個。
這是我所做的。
SELECT training_id, (5* COUNT()) AS [value]FROM progress
WHERE user_id IN (SELECT friend_id AS user_ids FROM friendships WHERE user_id=6 UNION SELECT user_id FROM membership WHERE team_id IN (SELECT team_id FROM membership WHERE user_id = 6))
AND completed = 1
GROUP BY training_id
UNION ALL
SELECT training_id, (10 * AVG(rating))
FROM reviews
WHERE user_id IN (SELECT friend_id AS user_ids FROM friendships WHERE user_id=6 UNION SELECT user_id FROM membership WHERE team_id IN (SELECT team_id FROM membership WHERE user_id = 6))
GROUP BY training_id
UNION ALL
SELECT training_id, COUNT()
FROM likes
WHERE user_id IN (SELECT friend_id AS user_ids FROM friendships WHERE user_id=6 UNION SELECT user_id FROM membership WHERE team_id IN (SELECT team_id FROM membership WHERE user_id = 6))
GROUP BY training_id
結果如下:
training_id value ______________________ 1 10 2 5 1 34.5 2 45 1 6 2 3
如果您知道這樣做的方法,或者是否有我應該考慮的替代方法,請告訴我。
(表'likes' 'reviews' 和'progress' 都包含字段“training_id”。你怎么看待加入這三個表開始?)
這相當令人印象深刻。 您的查詢結構良好且易於閱讀。 如果您想要每個 training_id 的總和,只需自己構建一個外部查詢:
select training_id, sum(value)
from (<your query here>) x
group by training_id
order by sum(value) desc;
至於加入表格:不,通常你不想這樣做。 您不想將每條進度記錄與每條評論記錄和每條training_id 的每條喜歡記錄連接起來。 這將使您的值成倍增加(例如,一次培訓的 2 個進度條目、3 條評論和 4 個贊將為您提供 2 x 3 x 4 = 24 條中間記錄)。 在您的特定情況下,這不會有什么害處,因為AVG
會產生相同的值,您可以將COUNT(*)
替換為COUNT(DISTINCT progress_id)
和COUNT(DISTINCT likes_id)
,但是一旦您使用SUM
您就會麻煩。
你可以做的是加入聚合:
with mates as
(
select friend_id as user_id from friendships where user_id = 6
union
select user_id from membership where team_id in
(select team_id from membership where user_id = 6)
)
select
training_id,
coalesce(p.value, 0) +
coalesce(r.value, 0) +
coalesce(l.value, 0) as total
from
(
select training_id, 5 * count(*) as value
from progress
where user_id in (select user_id from mates)
and completed = 1
group by training_id
) p
full outer join
(
select training_id, 10 * avg(rating) as value
from reviews
where user_id in (select user_id from mates)
group by training_id
) r using (training_id)
full outer join
(
select training_id, count(*) as value
from likes
where user_id in (select user_id from mates)
group by training_id
) l using (training_id)
order by 2 desc;
好的,感謝您的輸入。 我的第二個預感是對的。 我需要使用連接。 我只在文檔中閱讀了 Joins 並且不熟悉它們,但是一旦我嘗試過它,它就非常簡單。
這是解決方案。
SELECT training.*, ((10 * AVG(reviews.rating)) + COUNT(DISTINCT likes.user_id) + ( 5* COUNT(DISTINCT progress.trainee_id))) AS total FROM training JOIN likes ON training.training_id = likes.training_id JOIN reviews ON training.training_id = reviews.training_id JOIN progress ON training.training_id = progress.training_id WHERE user_id IN (SELECT friend_id AS user_ids FROM friendships WHERE user_id=6 UNION SELECT user_id FROM membership WHERE team_id IN (SELECT team_id FROM membership WHERE user_id = 6)) AND progress.completed = 1 AND progress.trainee_id IN (SELECT friend_id AS user_ids FROM friendships WHERE user_id=6 UNION SELECT user_id FROM membership WHERE team_id IN (SELECT team_id FROM membership WHERE user_id = 6)) ORDER BY total DESC GROUP BY training_name LIMIT 6
這給了我
training_id, training_name, total -- 這些是結果的字段名
1、初學者LiveCode,53
2、SQL 101、48
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.