2009-09-19 3 views
3

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

Узлов (п) таблицы: id

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

Тип (т) стол: id, priority

Я пытаюсь выбрать набор атрибутов, каждый из которых имеет самый низкий тип.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 с правильным атрибутом.

+0

@Stiggler: Что означает «неявно выбранный» для вас? –

+0

@Stiggler: Может ли атрибут быть связан с одним или несколькими node_id? Если да, это означает, что было бы два списка атрибутов с (возможно, разными) наименьшими приоритетами для любого количества узлов (при условии, что ATTRIBUTES.type_id не может быть нулевым). –

ответ

2

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

+0

Спасибо, Билл, это именно то, что я искал! Я понял, что эта конкретная проблема имела имя, но я не мог понять, что это было. Используя ваш примерный запрос, я построил запрос, который, кажется, выбирает именно то, что я хочу (мои фактические таблицы более сложны, чем примерные, которые я предоставил). Ваши замечания относительно связей также верны. К счастью, это не провал в дизайне, а то, что я планирую предотвратить, хотя я еще не сделал этого.На данный момент достаточно собрать любой из связанных строк. – Stiggler

+1

Хорошо, отлично, я рад, что смогу помочь. Просто, чтобы вы знали, это решение возвращает * обе строки в случаях, когда есть связи. –

2

Использование запроса тай-брейка (не проверено):

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 
        ) 
+1

@Van: Это MySQL - не должен «TOP 1» быть «LIMIT 1»? –

+0

@rexem: спасибо, изменено - надеюсь, что это правильно – van

 Смежные вопросы

  • Нет связанных вопросов^_^