首页 > 解决方案 > 联合 - 关键字“订单”附近的语法不正确

问题描述

表:电影

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| movie_id      | int     |
| title         | varchar |
+---------------+---------+

movie_id 是该表的主键。标题是电影的名称。表:用户

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| user_id       | int     |
| name          | varchar |
+---------------+---------+

user_id 是该表的主键。表:Movie_Rating

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| movie_id      | int     |
| user_id       | int     |
| rating        | int     |
| created_at    | date    |
+---------------+---------+

(movie_id, user_id) 是该表的主键。此表包含用户在其评论中对电影的评分。created_at 是用户的评论日期。

编写以下 SQL 查询:

查找对电影评分最多的用户的姓名。如果出现平局,则返回按字典顺序较小的用户名。

查找 2020 年 2 月平均评分最高的电影名称。如果出现平局,则返回字典顺序较小的电影名称。

查询分两行返回,查询结果格式如下例:

电影表:

+-------------+--------------+
| movie_id    |  title       |
+-------------+--------------+
| 1           | Avengers     |
| 2           | Frozen 2     |
| 3           | Joker        |
+-------------+--------------+

用户表:

+-------------+--------------+
| user_id     |  name        |
+-------------+--------------+
| 1           | Daniel       |
| 2           | Monica       |
| 3           | Maria        |
| 4           | James        |
+-------------+--------------+

Movie_Rating 表:

+-------------+--------------+--------------+-------------+
| movie_id    | user_id      | rating       | created_at  |
+-------------+--------------+--------------+-------------+
| 1           | 1            | 3            | 2020-01-12  |
| 1           | 2            | 4            | 2020-02-11  |
| 1           | 3            | 2            | 2020-02-12  |
| 1           | 4            | 1            | 2020-01-01  |
| 2           | 1            | 5            | 2020-02-17  | 
| 2           | 2            | 2            | 2020-02-01  | 
| 2           | 3            | 2            | 2020-03-01  |
| 3           | 1            | 3            | 2020-02-22  | 
| 3           | 2            | 4            | 2020-02-25  | 
+-------------+--------------+--------------+-------------+

结果表:

+--------------+
| results      |
+--------------+
| Daniel       |
| Frozen 2     |
+--------------+

丹尼尔和玛丽亚对 3 部电影(“复仇者联盟”、“冰雪奇缘 2”和“小丑”)进行了评级,但丹尼尔在词典上更小。《冰雪奇缘 2》和《小丑》在 2 月份的平均评分为 3.5,但《冰雪奇缘 2》的字典顺序较小。

这是我的解决方案:

(
  select top 1 u.name as results 
  from users as u
  join movie_rating as m on u.user_id = m.user_id
  group by user_id
  order by count(rating) desc, name
)
union all
(
  select top 1 m.title as results 
  from movies as m
  join movie_rating as r on m.movie_id = r.movie_id
  where CONVERT(varchar(7), r.created_at, 121) = '2020-02'
  group by m.title
  order by avg(rating) desc, m.title
);

我收到这个我无法弄清楚的错误

[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]关键字“order”附近的语法不正确。(156) (SQLExecDirectW)

任何想法以及如何解决它?

标签: sqlsql-server

解决方案


好的,我认为这可能有效,因为您没有提供 DDL/DML 语句,我无法对其进行测试。

注意事项:

  1. 对于联合的每个部分,您需要一个完整的派生查询,而不是子查询。
  2. 对于任何计算order by列,您需要在选择中计算它,然后order by是别名。
  3. 你不需要group by u.[name]u.[user_id]你必须group by选择你所选择的任何东西。
  4. 您缺少一些别名,这导致了不明确的列错误。
  5. 如果您想要avgint列,您必须将其转换decimal为某种类型的,以避免 SQL Server 自动将其四舍五入为int.
    select results, rating
    from (
      select top 1 u.[name] as results, count(convert(decimal(9,2),m.rating)) rating 
      from users as u
      join movie_rating as m on u.[user_id] = m.[user_id]
      group by u.[name]
      order by rating desc, results asc
    ) X

    union all

    select results, rating
    from (
      select top 1 m.title as results, avg(convert(decimal(9,2),r.rating)) Rating
      from movies as m
      join movie_rating as r on m.movie_id = r.movie_id
      where CONVERT(varchar(7), r.created_at, 121) = '2020-02'
      group by m.title
      order by rating desc, results asc
    ) X;

推荐阅读