Начинающий SQL-вопрос для базы данных рейтингов фильмов - PullRequest
1 голос
/ 26 ноября 2008

У меня есть база данных с одной таблицей, вот так:

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

Идентификаторы userID и movieID являются большими числами, но в моей базе данных имеется только выборка из множества возможных значений (4000 уникальных пользователей и 3000 уникальных фильмов)

Я собираюсь сделать матрицу SVD (разложение по сингулярным числам), поэтому я хочу вернуть эту базу данных в виде упорядоченного массива. По сути, я хочу вернуть каждого пользователя по порядку, а для каждого пользователя вернуть каждый фильм по порядку, а затем вернуть оценку для этого пользователя, пары фильмов или нуля, если этот пользователь не оценивал этот конкретный фильм. Пример:

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. (Любые другие предложения для получения базы данных информации в простой двумерный массив чисел с плавающей точкой будут приветствоваться)

Важно, чтобы это было возвращено для того, чтобы, когда я верну свой двумерный массив, я смог переназначить значения соответствующим пользователям и фильмам для моего анализа.

Ответы [ 3 ]

6 голосов
/ 26 ноября 2008
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;

Сейчас протестировано и похоже на работу!

Идея состоит в том, чтобы создать декартово произведение из списка значений UserID в таблице Ratings со списком значений MovieID в таблице Ratings (ой!), А затем выполнить внешнее соединение этой полной матрицы с таблицей Ratings. (снова), чтобы собрать значения оценок.

Это НЕ эффективно.

Это может быть эффективно.

Вы могли бы сделать лучше, хотя бы просто выполнить простой простой выбор данных и организовать заполнение массивов по мере поступления данных. Если у вас много тысяч пользователей и фильмов, вы будете возвращать много миллионов строк, но большинство из них будут иметь нулевые значения. Вы должны рассматривать входящие данные как описание разреженной матрицы, и сначала установить матрицу в программе на все нули (или другое значение по умолчанию), а затем прочитать поток из базы данных и установить только те строки, которые действительно присутствовали.

Этот запрос в основном тривиален:

SELECT UserID, MovieID, Rating
    FROM Ratings
    ORDER BY UserID, MovieID;
1 голос
/ 26 ноября 2008

Иногда лучше всего сделать рефакторинг таблицы / нормализовать ваши данные (если это вариант).

Нормализация структуры данных:

Таблица пользователей: (все отдельные пользователи)
UserId, Имя, Фамилия

Таблица фильмов: (все отдельные фильмы)
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

0 голосов
/ 26 ноября 2008

Если я правильно понимаю ваш вопрос, у вас есть все данные в вашей таблице, и вы просто хотите извлечь их в правильном порядке. Это верно? Если так, то это должно быть только значение:

select userid, movieid, rating
from ratings
order by userid, movieid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...