2010-05-17 64 views
0

我有一個擁有兩個表的數據庫。這兩個表格定義爲:SQL Server 2008 - 有條件範圍

Movie 
----- 
ID (int) 
Title (nvchar) 

MovieReview 
----------- 
ID (int) 
MovieID (int) 
StoryRating (decimal) 
HumorRating (decimal) 
ActingRating (decimal) 

我有一個存儲過程,允許用戶根據其他用戶的評論查詢電影。目前,我有一個填充了以下查詢的臨時表:

SELECT 
    m.*, 
    (SELECT COUNT(ID) FROM MovieReivew r WHERE r.MovieID=m.ID) as 'TotalReviews', 
    (SELECT AVG((r.StoryRating + r.HumorRating + r.ActingRating)/3) 
     FROM MovieReview r WHERE r.MovieID=m.ID) as 'AverageRating' 
FROM 
    Movie m 

在我的程序稍後查詢,我基本上想說:

SELECT 
    * 
FROM 
    MyTempTable t 
WHERE 
    t.AverageRating >= @lowestRating AND 
    t.AverageRating <= @highestRating 

我的問題是,有時AverageRating是零。因此,我不知道該怎麼做。我如何在SQL中處理這種情況?

+1

做你想做的事時AverageRating是零呢? – eKek0 2010-05-17 20:33:47

回答

0

我假設你想要在結果中包含零評論的電影。

SELECT 
    * 
FROM 
    MyTempTable t 
WHERE 
    (t.AverageRating >= @lowestRating AND 
    t.AverageRating <= @highestRating) 
    OR t.TotalReviews = 0 

測試TotalReviews是安全的,因爲它不會是NULL。

+0

doh!我忘記了OR部分。謝謝! – user208662 2010-05-17 20:40:45

+0

不客氣! – egrunin 2010-05-17 20:47:08

1

首先,我使用派生表來計算統計。這樣可以更容易地將零值轉換爲零(儘管如果我們在這裏使用Inner Join,則無需在TotalReviews上使用Coalesce)。

Select m.* 
    , Coalesce(MovieStats.TotalReviews, 0) As TotalReviews 
    , Coalesce(MovieStats.AverageRating, 0) As AverageRating 
From Movie As m 
    Join (
       Select R1.MovieId 
        , Count(*) As TotalReviews 
        , AVG((r.StoryRating + r.HumorRating + r.ActingRating)/3) As AverageRating 
       From MovieReview As r1 
       Group By R1.MovieId 
       ) As MovieStats 
     On MovieStats.MovieId = m.Id 
Where MovieStats.AverageRating Between @LowestRating And @HighestRating 

唯一這裏的問題是,通過把我們的過濾器在where子句中,這意味着我們必須在給定範圍內AverageRating值MovieReview記錄。

Select m.* 
    , Coalesce(MovieStats.TotalReviews, 0) As TotalReviews 
    , Coalesce(MovieStats.AverageRating, 0) As AverageRating 
From Movie As m 
    Left Join (
       Select R1.MovieId 
        , Count(*) As TotalReviews 
        , AVG((r.StoryRating + r.HumorRating + r.ActingRating)/3) As AverageRating 
       From MovieReview As r1 
       Group By R1.MovieId 
       ) As MovieStats 
      On MovieStats.MovieId = m.Id 
       And MovieStats.AverageRating Between @LowestRating And @HighestRating 

在沒有電影評級或電影評級存在超出傳遞範圍的情況下,這將返回零。

另一種可能性是在具有評價和強迫那些有在傳遞的範圍內平均收視值過濾:

Select m.* 
    , Coalesce(MovieStats.TotalReviews, 0) As TotalReviews 
    , Coalesce(MovieStats.AverageRating, 0) As AverageRating 
From Movie As m 
    Left Join (
       Select R1.MovieId 
        , Count(*) As TotalReviews 
        , AVG((r.StoryRating + r.HumorRating + r.ActingRating)/3) As AverageRating 
       From MovieReview As r1 
       Group By R1.MovieId 
       ) As MovieStats 
      On MovieStats.MovieId = m.Id 
Where MovieStats.MovieId Is Null 
    Or (MovieStats.AverageRating Between @LowestRating And @HighestRating) 
+0

+1:你是第一個 – 2010-05-17 20:41:01