如何优化此查询?

安娜·莱德尼科娃(Anna Lednikova)

我需要在PostgreSQL 9.3中编写以下查询:

  1. 列出每个国家/地区最受欢迎的电影。最受欢迎的电影是该国所有用户中获得最高平均评分的电影。如果打成平手,请按字母顺序返回所有电影的顺序。(2栏)

所需表:

CREATE TABLE movie (
id integer,
name varchar(200),
year date
);

CREATE TABLE userProfile (
userid varchar(200),
gender char(1),
age integer,
country varchar(200),
registered date
);

CREATE TABLE ratings (
mid integer,
userid varchar(200),
rating integer
);

CREATE INDEX movie_id_idx ON movie (id);
CREATE INDEX userProfile_userid_idx ON userProfile (userid);
CREATE INDEX ratings_userid_idx ON ratings (userid);
CREATE INDEX ratings_mid_idx ON ratings (mid);
CREATE INDEX ratings_userid_mid_idx ON ratings (userid, mid);

这是我的查询:

CREATE TEMP TABLE tops AS SELECT country, name 
FROM ratings AS r INNER JOIN userProfile AS u
ON r.userid=u.userid 
INNER JOIN movie AS m ON m.id = r.mid LIMIT 0;

~10 min
CREATE TEMP TABLE avg_country AS
SELECT country, r.mid, AVG(rating) AS rate
FROM ratings AS r INNER JOIN userProfile AS u
ON r.userid=u.userid 
GROUP BY country, r.mid;

~8 min
DO $$
DECLARE arrow record;
BEGIN
CREATE TABLE movie_names AS SELECT id, name FROM movie;
FOR arrow IN SELECT DISTINCT country FROM userProfile ORDER BY country
LOOP
  CREATE TABLE movies AS SELECT mid FROM (SELECT MAX(rate) AS m_rate FROM avg_country
  WHERE country=arrow.country) AS max_val CROSS JOIN LATERAL
  (SELECT mid FROM avg_country 
  WHERE country=arrow.country AND rate=max_val.m_rate) AS a;
  WITH names AS (DELETE FROM movie_names AS m 
  WHERE m.id IN (SELECT mid FROM movies) RETURNING name)
  INSERT INTO tops
  SELECT arrow.country, name FROM names ORDER BY name;
  DROP TABLE movies;
END LOOP;
DROP TABLE movie_names;
END$$;

SELECT * FROM tops;
DROP TABLE tops, avg_country;

非常感谢)

戈登·利诺夫

这类似于kordirkos的答案,但子查询少了一个:

select country, movie_name, avg_rating
from (select u.country, m.name as movie_name, avg(r.rating) as avg_rating
             rank() over (partition by u.country order by avg(r.rating) desc) as seqnum
      from userProfile u join
           ratings r
           on u.userid = r.userid join
           movie m
           on r.mid = m.id
      group by u.country, m.id -- `name` is not needed here because id is unique 
     ) uc
where seqnum = 1;

另外,如果您想将每个国家/地区的清单都排成一列,请执行以下操作:

select country, string_agg(movie_name, '; ') as most_popular_movies
from (select u.country, m.name as movie_name, avg(r.rating) as avg_rating
             rank() over (partition by u.country order by avg(r.rating) desc) as seqnum
      from userProfile u join
           ratings r
           on u.userid = r.userid join
           movie m
           on r.mid = m.id
      group by u.country, m.id -- `name` is not needed here because id is unique 
     ) uc
where seqnum = 1
group by country;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何优化此查询?

来自分类Dev

如何优化此LinQ查询?

来自分类Dev

如何优化此ActiveRecord查询?

来自分类Dev

如何优化此专用查询?

来自分类Dev

如何优化此SharePoint查询条款?

来自分类Dev

如何优化此MySQL查询以执行Fastar?

来自分类Dev

如何优化此SQL查询并缩短?

来自分类Dev

如何使用Rails优化此查询

来自分类Dev

如何优化在Postgresql中查询此数据?

来自分类Dev

如何使用whereHas优化此查询?

来自分类Dev

如何优化此查询以防止超时

来自分类Dev

请问如何优化此mysql查询?

来自分类Dev

如何优化此MySQL查询以执行Fastar?

来自分类Dev

如何使用表联接优化此查询?

来自分类Dev

如何使用Rails优化此查询

来自分类Dev

如何使用自联接优化此查询?

来自分类Dev

如何优化此查询?检索列的值

来自分类Dev

如何优化此查询的执行时间

来自分类Dev

如何在执行速度方面优化此查询

来自分类Dev

如何优化此依赖日期值的JOIN查询?

来自分类Dev

如何优化此MYSQL查询-联接多个表

来自分类Dev

我如何优化此查询以缩短执行时间

来自分类Dev

如何优化此 MySQL 查询 - 在视图中?性能调优

来自分类Dev

优化/简化此SQL查询

来自分类Dev

优化此查询中的计算?

来自分类Dev

优化/简化此SQL查询

来自分类Dev

如何优化此UDF

来自分类Dev

如何优化此功能

来自分类Dev

如何优化此代码?