简体   繁体   English

根据联接优先级列的最低值选择不同的标识行

[英]Selecting distinct identity rows based on the lowest value of a joined priority column

Simplified table structures, all INT columns and no PKs outside of the identity columns: 简化的表结构,所有INT列以及标识列之外的没有PK:

Nodes (n) table: id 节点(n)表: id

Attributes (a) table: id , node_id , type_id 属性(a)表: idnode_idtype_id

Type (t) table: id , priority 类型(t)表: idpriority

I'm trying to select a set of attributes, each of which has the lowest type.priority for its respective node. 我正在尝试选择一组属性,每个属性对于其各自的节点具有最低的type.priority。 Though there are multiple attributes per node_id , I only want to select the one with the lowest priority value: 虽然每个node_id有多个属性,但我只想选择具有最低优先级值的属性:

a1 n1 t1 p0 *
a2 n1 t2 p1 
a3 n2 t2 p1 *
a4 n2 t3 p2  

This is the basic query that I'm working from, at which point I'm also getting stuck: 这是我正在处理的基本查询,此时我也陷入困境:

   SELECT * 
     FROM a 
LEFT JOIN t ON a.type_id = t.id 
 GROUP BY node_id

My first thought was to use an aggregate, MIN, but I'm then having problems matching up the lowest priority for a node_id with the correct attribute. 我的第一个想法是使用聚合MIN,但是我遇到了将node_id的最低优先级与正确属性相匹配的问题。

Use tie-breaker query (not tested): 使用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
                    )

This question is a variation of the "greatest-n-per-group" problem, but you're looking for the least instead of the greatest, and your criteria are in a lookup table ( Type ) instead of the principle table ( Attributes ). 这个问题是“每组最大n”问题的变体,但是你要找的是最小的而不是最大的,你的标准是在查找表( Type )而不是主表( Attributes )中。

So you want the rows ( a1 ) from Attributes such that no other row with the same node_id is associated with a lower priority. 因此,您需要来自Attributes的行( a1 ),以使具有相同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;

Note that this can result in ties. 请注意,这可能会导致联系。 You haven't described how you would resolve ties if two Attributes referenced Types with the same priority. 如果两个属性引用具有相同优先级的类型,则您尚未描述如何解析关系。 In other words, in the following examples, which attributes should be selected? 换句话说,在以下示例中,应选择哪些属性?

a1 n1 t1 p0 
a2 n1 t1 p0 
a3 n2 t2 p1 
a4 n2 t3 p1 

PS: I hope you don't mind I added the "greatest-n-per-group" tag to your question. PS:我希望你不介意我在你的问题中添加了“最大n组”标签。 Click that tag to see other questions on SO that I have tagged similarly. 点击该标签可以查看我已经标记过类似的其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM