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


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