我需要帮助创建复杂的SQL查询。考虑以下表格(例如简化):
列表
list_id | user_id | list_type
-----------------------------------
1 | 1 | favorite movies
2 | 2 | favorite movies
list_items
list_id | movie_id
------------------
1 | 1
2 | 1
2 | 2
在此示例中,用户1已将电影1添加到他最喜欢的电影列表中。用户2已将电影1和电影2添加到他最喜欢的电影列表中。
我正在尝试输出所有其他电影的列表,每个添加了电影1的用户也会添加到他们喜欢的电影列表中,按频率排序。结果应该是:
movie_id | total_adds
---------------------
2 | 1
我有问题掌握如何使用COUNT和DISTINCT生成此输出,以及我是否可以以某种方式加入以减少处理开销。
答案 0 :(得分:3)
这是一种方法。
with
test_data ( user_id, movie_id ) as (
select 1, 1 from dual union all
select 2, 1 from dual union all
select 2, 2 from dual union all
select 2, 3 from dual union all
select 3, 2 from dual union all
select 3, 3 from dual union all
select 4, 1 from dual union all
select 4, 2 from dual union all
select 4, 9 from dual
)
-- End of test data (NOT part of the SQL query).
-- Solution (SQL query) begins BELOW THIS LINE. Use your actual table and column names.
select movie_id, count(*) as ct
from test_data
where user_id in ( select user_id from test_data where movie_id = 1 )
and movie_id != 1
group by movie_id
order by ct desc, movie_id
;
MOVIE_ID CT
---------- ----------
2 2
3 1
9 1
4 rows selected.
答案 1 :(得分:0)
这是另一种方式。它有点复杂,但取决于数据通常会更快:
WITH lists ( list_id, user_id ) AS (
SELECT 1, 1 FROM dual UNION ALL
SELECT 2, 2 FROM dual UNION ALL
SELECT 3, 2 FROM dual UNION ALL
SELECT 4, 2 FROM dual UNION ALL
SELECT 5, 3 FROM dual UNION ALL
SELECT 6, 3 FROM dual UNION ALL
SELECT 7, 4 FROM dual UNION ALL
SELECT 8, 4 FROM dual UNION ALL
SELECT 9, 4 FROM dual
), list_items (list_id, movie_id) AS (
SELECT 1, 1 FROM dual UNION ALL
SELECT 2, 1 FROM dual UNION ALL
SELECT 3, 2 FROM dual UNION ALL
SELECT 4, 3 FROM dual UNION ALL
SELECT 5, 2 FROM dual UNION ALL
SELECT 6, 3 FROM dual UNION ALL
SELECT 7, 1 FROM dual UNION ALL
SELECT 8, 2 FROM dual UNION ALL
SELECT 9, 9 FROM dual
), test_data (user_id, movie_id) AS (
SELECT user_id, movie_id FROM lists l
JOIN list_items li ON l.list_id=li.list_id
)
SELECT movie_id, count(*) ct
FROM (
SELECT user_id, movie_id, min(movie_id) OVER (PARTITION BY User_Id) min_movie_id
, SUM(CASE WHEN movie_id = 1 THEN 0 ELSE 1 END) OVER (PARTITION BY user_id) ct
FROM test_data
)
WHERE min_movie_id=1 AND movie_id<>1
GROUP BY movie_id
ORDER BY ct desc, movie_id
;
测试数据扩展回原始表格。结果与mathguy相同。