Выбор отдельных строк идентификатора на основе наименьшего значения объединенного столбца приоритета
-
11-09-2019 - |
Вопрос
Упрощенные структуры таблиц, все столбцы INT и никаких PKS за пределами столбцов identity:
Узлы (n) таблица: id
Атрибуты (a) таблица: id
, node_id
, type_id
Тип (t) таблица: id
, priority
Я пытаюсь выбрать набор атрибутов, каждый из которых имеет наименьший type.priority для соответствующего узла.Хотя существует несколько атрибутов для node_id
, Я хочу выбрать только тот, у которого наименьшее значение приоритета:
a1 n1 t1 p0 *
a2 n1 t2 p1
a3 n2 t2 p1 *
a4 n2 t3 p2
Это основной запрос, с которым я работаю, и в этот момент я тоже застреваю:
SELECT *
FROM a
LEFT JOIN t ON a.type_id = t.id
GROUP BY node_id
Моей первой мыслью было использовать агрегат MIN, но затем у меня возникли проблемы с сопоставлением самого низкого приоритета для node_id с правильным атрибутом.
Решение
Этот вопрос является вариацией проблемы "наибольшее число на группу", но вы ищете наименьшее, а не наибольшее, и ваши критерии приведены в таблице поиска (Type
) вместо принципиальной таблицы (Attributes
).
Итак, вам нужны строки (a1
) из Attributes
таким образом, чтобы ни одна другая строка с таким же node_id
связан с более низким приоритетом.
SELECT a1.*
FROM Attributes a1 INNER JOIN Type t1 ON (a1.type_id = t1.id)
LEFT OUTER JOIN (
(Attributes a2 INNER JOIN Type t2 ON (a2.type_id = t2.id))
ON (a1.node_id = a2.node_id AND t1.priority > t2.priority)
WHERE a2.node_id IS NULL;
Обратите внимание, что это может привести к возникновению связей.Вы не описали, как бы вы разрешали связи, если бы два атрибута ссылались на типы с одинаковым приоритетом.Другими словами, в следующих примерах какие атрибуты следует выбрать?
a1 n1 t1 p0
a2 n1 t1 p0
a3 n2 t2 p1
a4 n2 t3 p1
PS:Надеюсь, вы не возражаете, что я добавил к вашему вопросу тег "наибольшее число пользователей в группе".Нажмите на этот тег, чтобы просмотреть другие вопросы по теме, которые я пометил аналогично.
Другие советы
Используйте запрос tie-breaker (не тестировался):
SELECT n.*, a.*
FROM Nodes n
LEFT JOIN Attributes a
ON a.id = (SELECT x.id --//TOP 1 x.id
FROM Attributes x
INNER JOIN Type t
ON x.type_id = t.id
WHERE x.node_id = n.id
ORDER BY t.priority ASC,
--//just in case there are 2 attributes
--//with the same priority, order also on x.id
x.id ASC
LIMIT 1
)