我對 SQL 世界很陌生,我遇到了這個我能夠完成的提示,但我不得不想象我錯過了一個更直接和直觀的解決方案。我的解決方案在 SQLite 中回傳正確的回應,舍入誤差超過 10 位小數,但技術上與報告的解決方案不匹配。我很欣賞任何見解。
提示:求 1980 年以前上映的電影的平均收視率 [“stars”] 與 1980 年以后發行的電影的平均收視率之間的差值。(平均前后的差值。)
該資料庫包括 3 個具有以下列的表(為相關性而簡化):
movie| mID*, year
reviewer| rID*, name
rating| rID*, mI*, stars
"mavg" is my own aliased aggregation
select distinct(
(select avg(mavg)
from(
(select *, avg(stars) as mavg
from rating
group by mID) join movie using(mID) )
where year < 1980) -
(select avg(mavg)
from(
(select *, avg(stars) as mavg
from rating
group by mID) join movie using(mID) )
where year >= 1980)
)
from rating
;
uj5u.com熱心網友回復:
讓我們看看您的子查詢:
select *, avg(stars) as mavg
from rating
group by mID
這是一個無效的查詢。GROUP BY mid你說你想聚合你的行以獲得每個 mID 的一個結果行。但是,您不僅選擇了平均評分,還選擇了表 ( SELECT *) 中的所有列。這些列之一是stars。當一個 mID 有很多行時,如何將星星列選擇為一行?大多數 DBMS 在此處報告語法錯誤。SQLite 會從任何 mID 的行中任意選擇一顆星。因此,雖然這在 SQLite 中被認為是有效的,但在標準 SQL 中卻不是這樣,你不應該撰寫這樣的查詢。
對于結果(每部電影的平均值),您可以加入電影表。然后您選擇所需年份的電影的平均電影收視率。這做得很好,但是您可以將該限制(連接或IN子句或EXISTS子句)直接放入子查詢中,以便僅計算您想要的電影的平均值,而不是計算所有平均值,然后只保留一些電影和解雇他人。但這是一個小細節。
然后從舊平均值中減去新平均值。這意味著您從另一個值中減去一個值,最終得到您想要顯示的一個值。但是,除了選擇這個值( )之外,您還沒有明顯的理由SELECT (...) - (...)將該值與評級表( )鏈接起來,因此只要評級表中有行,就經常選擇所需的值。SELECT (...) - (...) FROM rating然后您會注意到這一點并申請DISTINCT洗掉您自己不必要地創建的行。DISTINCT非常非常經常是一個寫得不好的查詢的指標。當你認為你需要DISTINCT時,問問自己是什么讓這變得必要。重復的行從何而來?你自己創造的嗎?修改這個。
查詢可以這樣寫:
select
avg(case when m.year < 1980 then r.movie_rating end) -
avg(case when m.year >= 1980 then r.movie_rating end) as diff
from
(
select mid, avg(stars) as movie_rating
from rating
group by mid
) r
join movie m using (mid);
在聚合函式中使用 case 運算式稱為條件聚合,并且通常是使用不同聚合時的首選解決方案。
uj5u.com熱心網友回復:
您可以在此處使用以下單個查詢:
SELECT AVG(CASE WHEN m.year < 1980 THEN r.stars END) -
AVG(CASE WHEN m.year >= 1980 THEN r.stars END) AS mavg
FROM rating r
INNER JOIN movie m ON m.mID = r.mID;
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/480476.html
