Выбор отдельных строк идентификаторов на основе самого низкого значения объединенного приоритетного столбца - PullRequest
3 голосов
/ 19 сентября 2009

Упрощенные структуры таблиц, все столбцы INT и без PK вне столбцов идентификации:

Узлы (n) Таблица: id

Атрибуты (а) Таблица: id, node_id, type_id

Тип (т) Таблица: id, 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 с правильным атрибутом.

Ответы [ 2 ]

2 голосов
/ 20 сентября 2009

Этот вопрос является вариацией проблемы «наибольший n на группу», но вы ищете наименьшее, а не наибольшее, и ваши критерии находятся в таблице поиска (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: Надеюсь, вы не возражаете, я добавил в ваш вопрос тег "great-n-per-group". Нажмите на этот тег, чтобы увидеть другие вопросы о SO, которые я пометил аналогично.

2 голосов
/ 20 сентября 2009

Использовать запрос прерывателя связей (не проверено):

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
                    )
...