SQL-запрос для новичка в базе данных рейтингов фильмов

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

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

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

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

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
1 657
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
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 в таблице рейтингов со списком значений MovieID в таблице рейтингов (ой!), А затем выполнить внешнее соединение этой полной матрицы с таблицей рейтингов (снова) для сбора значений рейтингов.

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

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

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

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

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

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

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

Это не сработает, если пользователю нужен «массив» одинакового размера для каждого пользователя - он заявил, что не все пары идентификаторов пользователя / идентификатора фильма существуют в базе данных. Ваш ответ дает переменное количество записей на пользователя.

paxdiablo 26.11.2008 07:11

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

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

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

Другие вопросы по теме