Если я буду хранить свои оценки пользователей так:
+---------+-------+------------+
| user_id | score | created_at |
+---------+-------+------------+
| 1 | 100 | 2017-12-20 |
| 1 | 200 | 2017-12-21 |
| 2 | 110 | 2017-12-20 |
| 2 | 210 | 2017-12-21 |
| 3 | 120 | 2017-12-20 |
| 3 | 220 | 2017-12-21 |
+---------+-------+------------+
Как я смогу получить самую близкую запись для каждого пользователя с датой ввода?
Я дошел до
SELECT *, (abs(datediff("$some-input-date", created_at))) as diff FROM table order by diff
Что дало бы мне дату ввода 2017-12-19
:
+---------+-------+------------+------+
| user_id | score | created_at | diff |
+---------+-------+------------+------+
| 1 | 100 | 2017-12-20 | 1 |
| 2 | 110 | 2017-12-20 | 1 |
| 3 | 120 | 2017-12-20 | 1 |
| 1 | 200 | 2017-12-21 | 2 |
| 2 | 210 | 2017-12-21 | 2 |
| 3 | 220 | 2017-12-21 | 2 |
+---------+-------+------------+------+
Теперь мне нужны уникальные строки по user_id
, поэтому я предположил, что что-то вроде GROUP BY user_id
будет работать, но я получаю сообщение "Выражение SELECT в выражении GROUP BY" в MySQL 5.7. Как я могу группировать user_id
в этом сценарии?
(Я также использую доктрину, поэтому, если есть какой-то способ достичь этого, используя функции dql или доктрины, которые также будут полезны)
Хорошо, так что вы знаете, как получить разницу в дате, и вы хотите получить только верхний результат для конкретного пользователя, упорядоченный по разнице дат по возрастанию:
SELECT * FROM
--your current query
(SELECT *, (abs(datediff("$some-input-date", created_at))) as diff FROM table) as data_with_diffs
INNER JOIN
( --a query to find only the minimum diffs per user id
SELECT userID, MIN(abs(datediff("$some-input-date", created_at))) as min_diff
FROM table
GROUP BY userid
) as find_min_diffs
ON
data_with_diffs.userid = find_min_diffs.userid AND
data_with_diffs.diff = find_min_diffs.min_diff
Если вы выполняете два внутренних запроса в отдельности, вы увидите, как это работает. Есть и другие способы структурирования этого, но я подумал, что было бы лучше, если бы вы увидели, как все это висит вместе на основе того, что вы не понимаете/уже разработали
Запрос группировки выбирает только минимальный diff для определенного идентификатора пользователя. Запустив это как подзапрос и присоединив его к уже полученным данным, INNER JOIN будет отфильтровывать все строки, где diff не равен минимальной разности
Вы можете по-прежнему получать повторяющиеся строки для пользователя, если у них есть дата до и дата после с тем же разным (т.е. -1 и +1 - они являются ближайшими), поэтому вам, возможно, придется реализовать стратегию для решения что, как и выбор их MAX-оценки