SQL - SELECT子句中的递归条件

时间:2016-01-07 15:59:39

标签: sql sql-server

我不是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|

基本上逻辑是:

  1. 如果name 为空,则display_name = 'nickname'
  2. 如果name 唯一,则display_name = 'name'
  3. 如果name not_unique ,则display_name = 'name (nickname)'
  4. 我可以只使用一个SQL查询来实现吗?如果是这样 - 怎么样?如果不是 - 有哪些替代方案?

    目前我使用我的编程语言,但我必须为结果的每一行发送另一个SQL查询,以检查是否有其他具有相同名称的记录,对于筛选结果是可以的,但在检索整个时太贪心了桌子(4 000行并且不断增长)。

2 个答案:

答案 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