MySQL:合并行并返回默认值

时间:2013-04-30 14:10:15

标签: mysql merge coalesce ifnull

想象一下下表:

id | variant | name
-----------------------
1  | 1       | a
1  | 2       | b
1  | 3       | c
2  | 1       | d
2  | 2       | e
2  | 3       | NULL
3  | 1       | g

我需要运行哪个SQL语句来实现此目的:

  • 对于给定的ID和给定的变体,请获取此组合的名称。
  • 但是如果名称为NULL,则获取具有给定id但具有变量1的行的名称(变量1的名称永远不为NULL)。
  • 如果没有给定变量的行,请再次使用其中variant为1且具有相同ID的行。
  • 永远不会直接要求变体1。

这就像一个后退机制。或者您可以将其视为具有variant = 1的行的覆盖值。

示例:

  • id = 1,variant = 2:b
  • id = 1,variant = 3:c
  • id = 2,variant = 3:d
  • id = 3,variant = 5:g

这可能与SQL有关吗?如果该机制应用于更多领域,它是否表现良好?

谢谢!

更新

请注意,我希望此机制不仅适用于名称字段。应该有更多的列应该具有相同的行为 - 但每个列应该单独处理。

2 个答案:

答案 0 :(得分:2)

这应该使用LEFT JOIN来获取您需要的内容以获取可选值。

SELECT COALESCE(b.Name,a.Name)
FROM Table1 a
LEFT JOIN Table1 b
  ON a.id=b.id AND b.variant=@y
WHERE a.id=@x AND a.variant=1

An SQLFiddle to test with

性能方面,它取决于您需要如何应用查询来获取多个字段。如果您可以使用现有联接中的COALESCE来解决您的列选择,我看不出大问题,但如果您最终有多个自联接来解决它,则可能会出现问题。

答案 1 :(得分:0)

与往常一样,性能取决于您的数据结构,您拥有的行数以及您创建的索引。我建议这样的查询:

SELECT name FROM table WHERE id=@1 AND ((variant=@2 AND name IS NOT NULL) OR variant=1) ORDER BY variant DESC LIMIT 1