如果列不为null,则为distinct列选择多行,否则选择column为null的第一行

时间:2017-06-29 23:47:24

标签: sql oracle

我有一个有趣的查询需要执行。对于下面的表A,我想为不同的 userId 选择所有非空 phoneNumber ,但如果非空 phoneNumber 值不是存在不同的 userId 为不同的 userId 选择只有一个 null phoneNumber

表A

| id | userId | phoneNumber | emailAddress | 
 ------------------------------------------- 
| 1  |   1    | 0123456789  |     null     | 
| 2  |   1    | 1234567890  |     null     | 
| 3  |   1    |    null     |  test@gmail  | 
| 4  |   2    |    null     |  andy@yahoo  | 
| 5  |   2    |    null     |  andy@gmail  |

预期结果

| id | userId | phoneNumber | emailAddress |
-------------------------------------------
| 1  |   1    | 0123456789  |     null     |
| 2  |   1    | 1234567890  |     null     |
| 5  |   2    |    null     |  andy@gmail  |

我在下面编写了查询并返回了所需的结果,但我很想知道是否有更好,更优化的方法来实现这一目标。而不是写多个子查询。

SELECT * 
FROM A 
WHERE phoneNumber IS NOT NULL 
UNION 
SELECT * 
FROM A 
WHERE id IN (SELECT MAX(id) 
             FROM A WHERE phoneNumber IS NULL 
                AND userId NOT IN (SELECT userId 
                                   FROM A 
                                   WHERE phoneNumber IS NOT NULL) 
             GROUP BY userId)

1 个答案:

答案 0 :(得分:0)

您可以使用COUNT()ROW_NUMBER()分析函数:

SELECT *
FROM   (
  SELECT A.*,
         COUNT( phoneNumber) OVER ( PARTITION BY userId ) AS ct,
         ROW_NUMBER() OVER ( PARTITION BY userId ORDER BY id DESC ) AS rn
  FROM   A
)
WHERE  phoneNumber IS NOT NULL
OR     ( ct = 0 AND rn = 1 );