【问题标题】:Query for find the list of DISCRETE DECADE with the number of records查询 DISCRETE DECADE 列表的记录数
【发布时间】:2021-01-06 05:17:30
【问题描述】:

我有一个包含以下表格的数据库:

演员(id、fname、lname、性别)
电影(id、姓名、年份、等级)
DIRECTOR (id, fname, lname)
CAST(a_id、m_id、角色)
MOVIE_DIRECTOR (d_id, m_id)

现在我要检索以下问题的数据。

十年是连续 10 年的序列。例如,1965,1966,..., 1974 是十年,1967, 1968,...,1976 也是十年。找出电影数量最多的十年。
十年必须是独一无二的,就像我们不能有 1965-1974 和 1966-1975 等的十年。

这个确切的问题之前已经被问过,我收到了两个问题,但这些问题并没有给出 DISTINCT 几十年的时间。这些查询的十年是 1995-2004,而不是 1996-2005、1994-2003。它计算了每年的十年。

select y.year as decade_start, y.year + 9 as decade_end,
       count(*) as num_movies
from (select distinct year from movies) y join
     movies m
     on m.year >= y.year and m.year < y.year + 10
group by y.year
order by count(*) desc;

戈登·林诺夫

另一个是

WITH MOV AS
(
   SELECT year as movie_year, COUNT(id) as total_movies
   FROM MOVIE 
   GROUP BY year
)
SELECT
  m1.movie_year as decade_start,
  MAX(m2.movie_year) as decade_end,
  SUM(m2.total_movies) as total_movies
FROM MOV m1
LEFT JOIN MOV m2 ON (m2.movie_year BETWEEN m1.movie_year AND m1.movie_year + 9)
GROUP BY m1.movie_year
ORDER BY SUM(m2.total_movies) DESC

作者:LukStorms

另外,当我在 MySQL 工作台中运行这两个查询时,我得到了一个非常有趣的发现,即 Gordon 的第一个运行了 15 多秒,而 LukStorm 的运行不到一秒跑步。 谁能指出为什么这两个查询的时间会有如此大的差异?

MOVIES 表的样本数据:

+--------+--------------------------------------+------+-----------+
| id     | name                                 | year | rankscore |
+--------+--------------------------------------+------+-----------+
| 282455 | Roundhay Garden Scene                | 1888 |      NULL |
| 337409 | Traffic Crossing Leeds Bridge        | 1888 |      NULL |
| 218187 | Monkeyshines, No. 2                  | 1890 |      NULL |
| 218186 | Monkeyshines, No. 1                  | 1890 |       7.3 |
| 218188 | Monkeyshines, No. 3                  | 1890 |      NULL |
|  95175 | Duncan Smoking                       | 1891 |       3.6 |
| 230974 | Newark Athlete                       | 1891 |       4.3 |
|  95174 | Duncan or Devonald with Muslin Cloud | 1891 |       3.5 |
| 218116 | Monkey and Another, Boxing           | 1891 |       3.2 |
|  95171 | Duncan and Another, Blacksmith Shop  | 1891 |       3.5 |
+--------+--------------------------------------+------+-----------+

【问题讨论】:

  • 那么十年从哪里开始呢? 1970 - 1979 年还是 1965-1974 年?查询如何知道这一点?请添加一些示例数据和预期输出。
  • “找出电影数量最多的十年。十年必须是独一无二的,就像我们不能有 1965-1974 和 1966-1975 等的十年。”没有意义;如果您正在寻找数量最多的十年,您不在乎某个数量较少的十年是否重叠。你想找到最高的十年,然后寻找第二高的,不包括与之重叠的任何十年,以及第三高的不包括与前两个重叠的任何十年,等等?这有点奇怪。
  • 或者你想找到最高的十年(例如 1995-2004)然后对其他匹配的十年进行排名(1985-1994、1975-1984、...、2005-2014、2015-2024 , ...)?
  • 或者您只是想选择一些任意规则(例如,只有第一年以 0 结尾的十年)来制作离散的十年?告诉我们您希望它如何工作。
  • 我的错,我应该给出样本数据。电影表有 id、name 和 year 列。所以我们需要找到第一年(年份的最小值),在数据中是1888。所以十年将从1888-1897、1898-1907、1908-1918.....1998-2007开始。

标签: mysql sql


【解决方案1】:

(回答你关于时差的问题)

第二个查询利用公用表表达式在计算几十年前有效地按年份对电影计数进行分类。这需要 mysql 8 或 mariadb 10.2+。

【讨论】:

    【解决方案2】:

    第一个查询对整个表进行一次聚合,然后将数据乘以大约 10(十年中的年数)并进行另一次聚合。

    第二个查询可以通过多种方式执行。但鉴于它更高效,它可能正在做:

    • 按年份汇总完整数据。
    • 对聚合数据执行自联接,这大大减小了大小。
    • 再次聚合。

    假设每年有相当数量的年份和许多电影,这将更快。

    重要的是,我的答案将适用于 8.0 之前的 MySQL 版本。如果您想要 MySQL 8+ 中的高效版本,那么以下应该比任何一个都快:

    select m.year as decade_start, m.year + 9 as decade_end,
           count(*) as num_movies_in_year,
           sum(count(*)) over (order by y.year range between current row and 9 rows following) as num_movies_in_decade
    from movies m
    group by m.year;
    

    注意:这假设您每年都有电影。如果没有,那么您可以轻松地改用range 分区。

    我认为最初的答案已经足够老了,以至于 MySQL 不支持窗口函数,或者它明确地在旧版本的 MySQL 上。

    【讨论】:

      猜你喜欢
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-12
      相关资源
      最近更新 更多