我有一个包含一个表的数据库,如下所示:
UserID (int), MovieID (int), Rating (real)
userID和movieID是大号,但我的数据库只有许多可能值的样本(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算法。 (将信息数据库转换为简单的二维浮点数组的任何其他建议将不胜感激)
重要的是按顺序返回,以便当我获得二维数组时,我将能够将值重新映射到相应的用户和电影以进行分析。
答案 0 :(得分:6)
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表对该完整矩阵进行外连接(再次)收集评级值。
NOT 效率很高。
可能有效。
你可能会做得更好,只需运行简单的数据选择,并安排在数据到达时填充数组。如果你有成千上万的用户和电影,你将返回数百万行,但其中大多数都会有空值。您应该将传入数据视为稀疏矩阵的描述,并首先将程序中的矩阵设置为全零(或其他默认值),然后从数据库中读取流并仅设置实际存在的行。
该查询基本上是微不足道的:
SELECT UserID, MovieID, Rating
FROM Ratings
ORDER BY UserID, MovieID;
答案 1 :(得分:1)
有时,最好的办法是重构表格/规范化数据(如果这是一个选项)。
规范化数据结构:
用户表:(所有不同的用户)
UserId,FirstName,LastName
电影表:(所有截然不同的电影)
MovieId,名称
UserMovieRatings :(用户对电影的评分)
UserId,MovieId,评级
如果您想要用户和电影的每个组合,然后根据需要使用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
答案 2 :(得分:0)
如果我正确理解您的问题,您的表格中包含所有数据,而您只想按正确的顺序提取数据。那是对的吗?如果是这样,它应该只是一个特点:
select userid, movieid, rating
from ratings
order by userid, movieid