2013-04-30 95 views
0

想象一下如下表:MySQL的:合并行,返回默认值

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)。
  • 如果没有给定变体的行,请再次使用变量为1的行使用相同的ID。
  • 变体1从不直接请求。

这就像倒退机制。或者也可以把它看作与变体覆盖的行的值= 1。

实例:

  • ID = 1,变体= 2:乙
  • ID = 1,变体= 3:C
  • ID = 2,变体= 3:d
  • ID = 3,变体= 5:克

这是可能的SQL?如果该机制应用于更多领域,它表现不错吗?

谢谢!

更新:

请注意,我想不仅对name字段这种机制。应该有更多的列应该有相同的行为 - 但每个列应该自己处理。

+0

我认为你需要添加一个多列的例子来获得性能位的好答案。如果你的意思是应该对每个列自己进行处理,就像从变量x中获得的一样,如果该列的值为空,我的回答只是额外的COALESCE,但是这可能是一个糟糕的假设。 – 2013-04-30 14:34:53

回答

2

这应该做你需要使用LEFT JOIN得到什么可选的值。

SELECT COALESCE(b.Name,a.Name) 
FROM Table1 a 
LEFT JOIN Table1 b 
    ON a.id=b.id AND [email protected] 
WHERE [email protected] AND a.variant=1 

An SQLFiddle to test with

性能方面,这取决于您如何应用查询来获取多个字段。如果您可以使用来自现有连接的COALESCE解决您的列选择问题,那么我看不到一个大问题,但如果最终有多个自连接来解决问题,则可能有问题。

+1

是的,这是解决方案!我已经与COALESCE一起尝试过了,但已经获得了不止一行。但你的解决方案是正确的。还有更多的专栏。非常感谢您的快速响应! – robsch 2013-04-30 14:41:12

0

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

SELECT name FROM table WHERE [email protected] AND (([email protected] AND name IS NOT NULL) OR variant=1) ORDER BY variant DESC LIMIT 1 
+0

不幸的是,这个解决方案不适用于更多的数据列。约阿希姆斯的解决方案似乎是完美的。但是谢谢你的帮助。 – robsch 2013-04-30 14:38:52

+0

如果你做得对,它肯定可以处理更多的数据列。但它一次不能用于多条记录。很高兴你有你需要的。 – 2013-04-30 16:05:23