【问题标题】:SQL COUNT to count all the numbers from another tableSQL COUNT 计算另一个表中的所有数字
【发布时间】:2014-10-28 05:55:18
【问题描述】:

我正在编写一个查询,以在喜剧类型的电影中选择最多的总提名。到目前为止,我有以下查询

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) 和自学的初学者。

我查看了多个在线教程,但到目前为止没有任何帮助。

感谢大家的帮助。

【问题讨论】:

  • 你的问题有点含糊。您是说您的“动机是获得一个类型喜剧电影提名次数最多的结果”,但是,在您的查询中,您按 Movie_Title 和 Release_Year 进行分组。这个 group by 不会只用一行来吸引你,它会为你提供多年来提名数量最多的电影。
  • 以下答案是正确的,但是,如果您只想获得那一行(提名最高的电影),您可以从 GROUP BY 和 SELECT 中删除“release_year”。

标签: sql oracle oracle11g


【解决方案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>

【讨论】:

    【解决方案2】:
    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
    

    【讨论】:

    • 但根据问题,他只想得到一个结果——提名数量最多的电影。您正在按电影标题和年份分组。
    • 没有 ERD 和样本数据,很难甚至不可能弄清楚表的语义。我认为movie_titlerelease_yearmovie 的主键,并且与nomination 存在1:n 关系。
    • 点!作为对这个问题的评论,我已经提到了这一点。希望对 OP 有所帮助。
    【解决方案3】:

    如果按提名数量排序查询,得到“第一”:

    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 ( ... )

    【讨论】:

      【解决方案4】:

      试试这样的:

      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. 从表 NOMINATION 开始,因为您想计算这些。
      2. Left 将电影类型加入提名的每一行,然后按类型过滤
      3. 对结果进行分组,以便统计同一部电影的提名情况
      4. 按降序排列结果集

      为了更好地理解该过程,请逐行尝试上述查询并查看其间的结果。刚执行前两行时,首先查看结果。然后添加第三行并再次执行。以此类推。

      更新(移除 LIMIT 后):
      将上面的 SELECT 语句包裹在

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

      更多详情请参阅How do I limit the number of rows returned by an Oracle query after ordering?

      【讨论】:

        【解决方案5】:

        最好使用join

        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

        【讨论】:

          猜你喜欢
          • 2017-10-16
          • 1970-01-01
          • 1970-01-01
          • 2017-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多