3

简化的表结构,所有 INT 列,并且没有标识列之外的 PK:

节点 (n)表:id

属性(一)表: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 的最低优先级时遇到了问题。

4

2 回答 2

2

使用 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
                    )
于 2009-09-19T21:10:35.663 回答
2

这个问题是“每组最大 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:我希望你不介意我在你的问题中添加了“greatest-n-per-group”标签。单击该标签以查看我已类似标记的关于 SO 的其他问题。

于 2009-09-20T00:10:33.097 回答