Sql 如果列不为空,请为不同的列选择多行,否则请选择列为空的第一行
我需要执行一个有趣的查询。对于下表A,我想为distinctuserId选择所有非空phoneNumber,但如果distinctuserId不存在非空phoneNumber值,则为distinctuserId选择仅一个nullphoneNumber 表ASql 如果列不为空,请为不同的列选择多行,否则请选择列为空的第一行,sql,oracle,Sql,Oracle,我需要执行一个有趣的查询。对于下表A,我想为distinctuserId选择所有非空phoneNumber,但如果distinctuserId不存在非空phoneNumber值,则为distinctuserId选择仅一个nullphoneNumber 表A | id | userId | phoneNumber | emailAddress | ------------------------------------------- | 1 | 1 | 0123456789 |
| 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)
您可以使用
COUNT()
和ROW\u 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 );
考虑到你的代码已经达到了预期的结果,这个问题可能更适合:)那么:如果一个ID至少有一个非空电话号码,你必须返回不同的非空电话号码?也就是说,对于每个不同的非空电话号码,只需选择其中一行(id、phonenumber)(以其碰巧拥有的电子邮件地址为准)?如果一个id的所有电话号码都是空的,那么只需为该id选择一行(任意一行)?