仅在符合ON条件的行上使用MAX

时间:2012-05-05 04:54:20

标签: mysql join

如何修改以下查询以将choice的添加限制为每nid只有一行,foo字段中值最高的一行?也就是说,choice表中有多个行具有相同的nid,我希望每个foo的最高nid加入node

SELECT *
FROM `node`
LEFT JOIN `choice` ON node.nid = choice.nid

2 个答案:

答案 0 :(得分:2)

SELECT *
  FROM node
  LEFT JOIN choice c USING (nid)
 WHERE (c.nid, c.foo) IN (SELECT nid, max(foo) FROM choice GROUP BY nid);

Try it out on SQLFiddle


修改

说到将bar添加到列表中。

在子查询中,我为MAX(foo)找到了nid,因此GROUP BY nid。在添加bar时没有逻辑,您应该在该列上使用聚合或将其包含在GROUP BY中。这是MySQL“扩展”(我个人觉得容易出错),它可以让你做出这样的事情。我假设MySQL在幕后做MAX(bar)。 如果你要运行查询:

mysql> SELECT nid, max(foo), max(bar) FROM choice GROUP BY nid;
+------+----------+------+
| nid  | max(foo) | bar  |
+------+----------+------+
|    1 |        3 | Uno  |
|    2 |        1 | Eins |
+------+----------+------+

您会看到,MAX(foo)MAX(bar)来自不同的行。 将输出与以下内容进行比较:

SELECT nid, max(foo), bar FROM choice GROUP BY nid;

只要nid + foo组合在choice内唯一,我就建议将更多值添加到子查询中。否则,需要改变整体方法。

答案 1 :(得分:1)

你可以通过这样的连接非常有效地完成这项工作:

SELECT *
FROM node
LEFT JOIN choice c1
  ON c1.nid = node.nid
LEFT JOIN choice c2
  ON c2.nid = node.nid
  AND c2.foo > c1.foo
WHERE c2.foo IS NULL

回到这个方法的一个方法是,如果你有重复foo的记录,你将得到重复的记录。