【问题标题】:Novice SQL query question for a movie ratings database电影分级数据库的新手 SQL 查询问题
【发布时间】:2008-11-26 03:18:07
【问题描述】:

我有一个只有一张表的数据库,如下所示:

UserID (int), MovieID (int), Rating (real)

用户 ID 和电影 ID 是很大的数字,但我的数据库只有许多可能值的样本(4000 个唯一用户和 3000 个唯一电影)

我将对其进行矩阵 SVD(奇异值分解),因此我想将此数据库作为有序数组返回。基本上,我想按顺序返回每个用户,对于每个用户,按顺序返回每部电影,然后返回该用户、电影对的评分,如果该用户没有对该特定电影评分,则返回 null。示例:

USERID | MOVIEID | RATING
-------------------------
99835   8847874    4
99835   8994385    3
99835   9001934    null
99835   3235524    2
           .
           .
           .
109834  8847874    null
109834  8994385    1
109834  9001934    null

etc

这样,我可以简单地将这些结果读入一个二维数组,适合我的 SVD 算法。 (任何其他关于将信息数据库放入一个简单的二维浮点数组的建议都将不胜感激)

按顺序返回这一点很重要,这样当我取回二维数组时,我将能够将值重新映射到相应的用户和电影以进行分析。

【问题讨论】:

    标签: sql database sql-server-2005


    【解决方案1】:
    SELECT m.UserID, m.MovieID, r.Rating
        FROM (SELECT a.userid, b.movieid
                  FROM (SELECT DISTINCT UserID FROM Ratings) AS a,
                       (SELECT DISTINCT MovieID FROM Ratings) AS b
             ) AS m LEFT OUTER JOIN Ratings AS r
             ON (m.MovieID = r.MovieID AND m.UserID = r.UserID)
        ORDER BY m.UserID, m.MovieID;
    

    现在经过测试,似乎可以工作了!

    这个概念是创建 Ratings 表中 UserID 值列表与 Ratings 表中 MovieID 值列表的笛卡尔积(哎呀!),然后将该完整矩阵与 Ratings 表进行外连接(再次)收集评分值。

    这是高效的。

    这可能是有效的。

    您最好只运行简单的数据选择,并安排在数据到达时填充数组。如果您有成千上万的用户和电影,您将返回数百万行,但其中大多数将有空值。您应该将传入的数据视为稀疏矩阵的描述,并首先将程序中的矩阵设置为全零(或其他默认值),然后从数据库中读取流并仅设置实际存在的行。

    该查询基本上是微不足道的:

    SELECT UserID, MovieID, Rating
        FROM Ratings
        ORDER BY UserID, MovieID;
    

    【讨论】:

      【解决方案2】:

      有时最好的办法是重构表/规范化您的数据(如果这是一个选项)。

      规范化数据结构:

      用户表:(所有不同的用户)
      用户 ID、名字、姓氏

      电影表:(所有不同的电影)
      电影 ID、名称

      UserMovieRatings:(用户对电影的评分)
      用户 ID、电影 ID、评级

      如果您想要用户和电影的每个组合,您可以进行笛卡尔连接,然后根据需要使用 UserMovieRatings 表。

      现在最好在系统变得更复杂之前进行重构。提前花点时间,我很肯定您需要提出的任何问题都会自然而然地出现...希望对您有所帮助...

      示例查询:

      select UserId, FirstName, LastName, MoveId, Name, cast(null as int) as Rating into #FinalResults from Users cross join Movies update #FinalResults set Rating = UMR.Rating from #FinalResults FR inner join UserMovieRatings UMR on FR.UserId = UMR.UserId and FR.MovieId = UMR.MovieId

      【讨论】:

        【解决方案3】:

        如果我正确理解您的问题,您的表中就有所有数据,您只想按正确的顺序提取它。那是对的吗?如果是这样,那应该只是以下问题:

        select userid, movieid, rating
        from ratings
        order by userid, movieid
        

        【讨论】:

        • 如果用户想要的是每个用户的相同大小的“数组”,这将不起作用 - 他表示并非所有用户 ID/电影 ID 对都存在于数据库中。您的回答为每个用户提供了可变数量的记录。
        猜你喜欢
        • 2011-08-26
        • 2012-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 1970-01-01
        相关资源
        最近更新 更多