0

想象一下下表:

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

这就像一个后备机制。或者您可以将其视为变体 = 1 的行的覆盖值。

例子:

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

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

谢谢!

更新:

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

4

2 回答 2

2

这应该做你需要使用 aLEFT 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

一个用于测试的 SQLFiddle

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

于 2013-04-30T14:25:01.133 回答
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
于 2013-04-30T14:17:24.473 回答