2014-10-28 79 views
0

我正在撰寫一個查詢來選擇風格喜劇電影中總數最多的提名人數。我有以下查詢到目前爲止SQL COUNT來統計來自其他表的所有數字

SELECT m.movie_title, m.release_year, COUNT(*) 
FROM MOVIE m JOIN NOMINATION n 
ON (n.movie_title=m.movie_title AND n.release_year=m.release_year) 
WHERE m.genre='Comedy' GROUP BY m.movie_title, m.release_year; 

如果我執行以下查詢

SELECT m.movie_title, m.release_year 
FROM MOVIE m 
WHERE (m.genre='Comedy') GROUP BY m.movie_title,m.release_year); 

它返回我與3個結果。我的動機是以流派喜劇的電影提名人數最高。

我的邏輯不正確?我還是一個初學sql(oracle11g)和自學的人。

我已經看過多個在線教程,但目前爲止還沒有任何幫助。

謝謝你的幫助。

+0

你的問題是有點模糊。你的意思是你的「動機是獲得一個具有最高提名的電影類型喜劇提名結果」,但是,在你的查詢中,你正按照Movie_Title和Release_Year進行分組。這個小組不會只用一行來獲取你,它會爲你提供多年來提名次數最多的電影。 – Vaibhav 2014-10-28 06:37:00

+0

下面的答案是正確的,但是,如果您只想獲得一行(最高提名的電影),您可以從GROUP BY和SELECT中刪除「release_year」。 – Vaibhav 2014-10-28 06:42:26

回答

1

嘗試是這樣的:

SELECT n.movie_title, n.release_year, COUNT(*) nominations 
FROM NOMINATION n 
LEFT JOIN MOVIE m ON n.movie_title=m.movie_title AND n.release_year=m.release_year 
WHERE m.genre='Comedy' 
GROUP BY n.movie_title,n.release_year 
ORDER BY nominations DESC 

你的做法是:

  1. 開始用表提名,因爲你要算那些。
  2. 左加入電影類型每一行中提名,然後按流派過濾
  3. 組的結果可以算提名爲同一部電影
  4. 秩序的結果降序排列

設置爲了更好地理解這個過程,請嘗試使用上面的查詢行來查看結果。當執行前兩行時,首先查看結果。然後添加第三行並再次執行。等等。

更新(後除去LIMIT):
裹在

SELECT * FROM (
... above statement here ... 
) WHERE ROWNUM=1; 

上述SELECT語句參見How do I limit the number of rows returned by an Oracle query after ordering?進一步的細節。

1

讓我們用僱員表例子來理解它。

我有三行顯示每個部門的計數(*)。

SQL> WITH data AS 
    2 (SELECT deptno, COUNT(*) rn FROM emp GROUP BY deptno 
    3 ) 
    4 SELECT * FROM DATA 
    5/

    DEPTNO   RN 
---------- ---------- 
     30   6 
     20   5 
     10   3 

現在,我想要一個具有最多部門數的行。

SQL> WITH data AS 
    2 (SELECT deptno, COUNT(*) rn FROM emp GROUP BY deptno 
    3 ) 
    4 SELECT * FROM DATA WHERE rn = 
    5 (SELECT MAX(rn) FROM data 
    6 ) 
    7/

    DEPTNO   RN 
---------- ---------- 
     30   6 

SQL> 

或者,也可以寫成:

SQL> WITH data1 AS 
    2 (SELECT deptno, COUNT(*) rn FROM emp GROUP BY deptno 
    3 ), 
    4 data2 AS 
    5 (SELECT MAX(rn) max_rn FROM DATA1 
    6 ) 
    7 SELECT d1.* FROM data1 d1, data2 d2 WHERE d1.rn = d2.max_rn 
    8/

    DEPTNO   RN 
---------- ---------- 
     30   6 

SQL> 

所以,你的情況,使用MAX功能。

其他方法是使用ANALYTIC函數,ROW_NUMBERRANK分配給每個計數(*),然後選擇最高等級。

例如,

SQL> WITH data AS 
    2 (SELECT deptno, 
    3  row_number() OVER(ORDER BY COUNT(*) DESC) rn 
    4 FROM emp 
    5 GROUP BY deptno 
    6 ) 
    7 SELECT deptno FROM DATA WHERE rn = 1 
    8/

    DEPTNO 
---------- 
     30 

SQL> 
1
select * from (
    select 
    movie_title, 
    release_year, 
    row_number() over (order by count(*) desc) rnk 
    from 
    movie m join 
    nomination n using(movie_title, release_year) 
    where 
    m.genre = 'Comedy' 
    group by 
    movie_title, 
    release_year 
) 
where 
    rnk = 1 
+0

但根據問題他只想得到一個結果 - 提名數最高的電影。您正按照電影標題以及年份進行分組。 – Vaibhav 2014-10-28 06:31:39

+0

沒有ERD和樣本數據,它很難找出表格的語義。我認爲'movie_title'和'release_year'是'movie'的主鍵,並且與'nomination'有1:n的關係。 – 2014-10-28 06:35:47

+0

Point!我已經提到這是對這個問題的評論。希望它有助於OP。 – Vaibhav 2014-10-28 06:46:47

1

如果你爲了你根據提名數查詢並獲得「第一」之一:

select movie_title, release_year, cnt 
from (
    SELECT m.movie_title, m.release_year, count(n.movie_title) as cnt 
    FROM MOVIE m 
    LEFT JOIN NOMINATIONS n 
     ON n.movie_title=m.movie_title 
     AND n.release_year=m.release_year 
    WHERE m.genre='Comedy' 
    GROUP BY m.movie_title,m.release_year 
    ORDER BY COUNT(n.movie_title) desc 
) 
where rownum = 1; 

另一種選擇是使用窗口功能和count(...) over (...)

0

這是更好地使用一個加入

SELECT (select COUNT(*) from NOMINATION As COUNT), m.movie_title, m.release_year,n.movie_title,n.release_year FROM MOVIE m Join NOMINATION On n.movie_title=m.movie_title AND n.release_year=m.release_year WHERE m.genre='Comedy' GROUP BY m.movie_title,m.release_year