SQL Запрос, л oop через данные - PullRequest
0 голосов
/ 06 января 2020

У меня есть база данных со следующими полями: UserID, DateRecorded и Score.

Новая запись добавляется в таблицу каждый раз, когда обновляется счет. Вот пример пользовательской записи:

UserID | DateRecorded | Score
3 | 21-08-2019 | 10
3 | 23-08-2019 | 5
3 | 21-09-2019 | 10
3 | 21-08-2018 | 1

Из запроса я хотел бы показать мне только оценки всех пользователей с самой ранней датой записи.

Хотя я не очень хорошо знаком с курсорами, я попытался использовать пример из net и адаптировал его к моему, но, похоже, это не сработало. Вот моя попытка с курсором:

DECLARE @DateRecorded AS DATETIME;
DECLARE @scores AS FLOAT;
DECLARE @Cursor as CURSOR;

SET @Cursor = CURSOR FOR
select [user_id], [DateRecorded], scores
from myTable
where [user_id] = '55'

OPEN @Cursor
FETCH NEXT FROM @Cursor INTO @UserID, @DateRecorded, @scores;

WHILE @@FETCH_STATUS = 0
BEGIN
 SELECT @UserID AS 'User ID', MIN(@DateRecorded) AS 'Date', @scores AS 'Score';
 FETCH NEXT FROM @Cursor INTO @UserID, @DateRecorded, @scores;
END

CLOSE @Cursor;
DEALLOCATE @Cursor;

Вот ожидаемые результаты:

3 | 21-08-2018 | 1

Есть ли более простой способ сделать это, чем использовать курсоры?

Полностью ли я неправильно понял курсоры?

Спасибо за помощь

1 Ответ

1 голос
/ 06 января 2020

Не используйте курсоры и циклы (если у вас нет другого выбора): они сложные и очень медленные. То, что вы просите здесь, можно сделать с помощью простых SQL запросов.

Если вы просто хотите получить самую раннюю дату записи для пользователя и никакой другой информации, тогда достаточно простого объединения:

select UserIdD, min(DateRecorded) from mytable group by UserID

Если вам нужна вся «первая» запись на пользователя, то это типичная проблема с наибольшим числом групп. Один из методов - фильтрация с помощью коррелированного подзапроса:

select t.*
from mytable t
where t.DateRecorded = (
    select min(t1.DateRecorded) from mytable t1 where t1.UserID = t.UserID
)

Вам также может понравиться решение anti- left join:

select t.*
from mytable t
left join mytable t1 on t1.UserID = t.UserID and t1.DateRecorded < t.DateRecorded
where t1.UserID is null
...