我不是SQL中最好的,所以如果我问愚蠢的问题很抱歉:)
我们有一个这样的表:
|id| name | nickname |
|==|========|============|
| 1| Jo| Banana|
| 2|Margaret|The Princess|
| 3| Perry| The Monkey|
| 4|Margaret| The Queen|
| 5| | The Rat|
| 6| | The Cat|
其中nickname
始终是唯一的。
我试图得到这样的结果:
|id| name | nickname | display_name |
|==|========|============|=======================|
| 1| Jo| Banana| Jo|
| 2|Margaret|The Princess|Margaret (The Princess)
| 3| Perry| The Monkey| Perry|
| 4|Margaret| The Queen| Margaret (The Queen)|
| 5| | The Rat| The Rat|
| 6| | The Cat| The Cat|
基本上逻辑是:
name
为空,则display_name = 'nickname'
name
唯一,则display_name = 'name'
name
not_unique ,则display_name = 'name (nickname)'
我可以只使用一个SQL查询来实现吗?如果是这样 - 怎么样?如果不是 - 有哪些替代方案?
目前我使用我的编程语言,但我必须为结果的每一行发送另一个SQL查询,以检查是否有其他具有相同名称的记录,对于筛选结果是可以的,但在检索整个时太贪心了桌子(4 000行并且不断增长)。
答案 0 :(得分:7)
您可以使用COUNT()
的窗口函数版本来确定给定行的name
是否唯一,而不执行子查询。例如:
SELECT
id, name, nickname,
CASE
WHEN ISNULL(name, '') = '' THEN nickname
WHEN (COUNT(*) OVER (PARTITION BY name)) = 1 THEN name
ELSE name + ' (' + nickname + ')'
END AS display_name
FROM my_table
答案 1 :(得分:2)
你可以试试这个 -
SELECT
*
,display_name =
CASE
WHEN (ROW_NUMBER() OVER (PARTITION BY name ORDER BY id) = 1) THEN name
WHEN ISNULL(name, '') = '' THEN nickname
ELSE name + ' (' + nickname + ')'
END
FROM MyTable