Выбор отдельных строк идентификатора на основе наименьшего значения объединенного столбца приоритета

StackOverflow https://stackoverflow.com/questions/1449143

  •  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
                    )
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top