SQL查询从空值表中查找最大值

SQL查询从空值表中查找最大值,sql,sql-server,Sql,Sql Server,我怎样才能满足这个要求呢。请帮忙 客户表-CT ClientID Balance 123 10 123 20 123 30 123 40 124 50 124 60 124 Null 我想从CT表中找到我们的最大值(余额)。 条件->如果没有空值,那么我必须找出max(Balance),否则它应该为

我怎样才能满足这个要求呢。请帮忙

客户表-CT

ClientID      Balance  
123             10
123             20  
123             30
123             40  
124             50
124             60  
124             Null  
我想从CT表中找到我们的最大值(余额)。
条件->如果没有空值,那么我必须找出max(Balance),否则它应该为空。看到下面的结果,我期待

ClientID     Balance  
123           40  
124           Null
我写的查询如下。但有没有更具活力的方式呢

Select ClientID,  
       CASE WHEN MIN(Balance) = NULL THEN  
                 NULL  
             ELSE  
                 MAX(Balance) END AS 'MaxBalance'  
From CT  
Group by clientID  
请告诉我,还有其他选择吗?

试试这个:

Select ClientID,
       (CASE WHEN count(balance) < count(*)
             THEN NULL 
             ELSE MAX(Balance)
        END) AS MaxBalance
From CT
Group by clientID  
试试这个:

Select ClientID,
       (CASE WHEN count(balance) < count(*)
             THEN NULL 
             ELSE MAX(Balance)
        END) AS MaxBalance
From CT
Group by clientID  
那么:

SELECT clientid
    , balance
FROM 
    ( 

        SELECT clientid
            , balance
            , row_number()
                over(   partition by clientid
                    order by CASE WHEN balance IS NULL THEN 0 ELSE 1 END
                        , balance DESC
                ) r
        FROM ct
    ) n 
WHERE r = 1
那么:

SELECT clientid
    , balance
FROM 
    ( 

        SELECT clientid
            , balance
            , row_number()
                over(   partition by clientid
                    order by CASE WHEN balance IS NULL THEN 0 ELSE 1 END
                        , balance DESC
                ) r
        FROM ct
    ) n 
WHERE r = 1

这将适用于SQL2005+

; WITH a AS (       
SELECT DISTINCT ClientID
FROM CT 
WHERE Balance IS NULL   )     

SELECT t.ClientID, MAX(t.Balance) "MaxBalance"
FROM CT t
    LEFT JOIN a ON t.CLientID = a.ClientID
WHERE a.ClientID IS NULL
GROUP BY t.CLientID
UNION ALL
SELECT a.ClientID, NULL
FROM a

这将适用于SQL2005+

; WITH a AS (       
SELECT DISTINCT ClientID
FROM CT 
WHERE Balance IS NULL   )     

SELECT t.ClientID, MAX(t.Balance) "MaxBalance"
FROM CT t
    LEFT JOIN a ON t.CLientID = a.ClientID
WHERE a.ClientID IS NULL
GROUP BY t.CLientID
UNION ALL
SELECT a.ClientID, NULL
FROM a

这很管用,但不是很优雅:

SELECT SUB.ClientID, CASE (SELECT COUNT(ClientID) 
                           FROM MyTable MT 
                           WHERE Balance IS NULL 
                           AND MT.ClientID = SUB.ClientID)
                    WHEN 0 THEN (SELECT MAX(Balance) 
                                 FROM MyTable MT 
                                 WHERE MT.ClientID = SUB.ClientID)
                    ELSE NULL END AS Balance
FROM (SELECT ClientID 
      FROM [MyTable] 
      GROUP BY ClientID) SUB

这很管用,但不是很优雅:

SELECT SUB.ClientID, CASE (SELECT COUNT(ClientID) 
                           FROM MyTable MT 
                           WHERE Balance IS NULL 
                           AND MT.ClientID = SUB.ClientID)
                    WHEN 0 THEN (SELECT MAX(Balance) 
                                 FROM MyTable MT 
                                 WHERE MT.ClientID = SUB.ClientID)
                    ELSE NULL END AS Balance
FROM (SELECT ClientID 
      FROM [MyTable] 
      GROUP BY ClientID) SUB

我不确定[Balance]是什么数据类型,但如果它是int,则可以执行以下操作:

Select ClientID, NULLIF(MAX(ISNULL(Balance,2147483647)),2147483647)
From CT 
GROUP BY ClientID
如果[Balance]不是整数,只需用该数据类型的最大值替换
2147483647


当然,危险在于,如果你真的有一个余额为2147483647的客户。在这种情况下,它们的最大余额将显示为null。

我不确定[balance]是什么数据类型,但如果是int,则可以执行以下操作:

Select ClientID, NULLIF(MAX(ISNULL(Balance,2147483647)),2147483647)
From CT 
GROUP BY ClientID
如果[Balance]不是整数,只需用该数据类型的最大值替换
2147483647


当然,危险在于,如果你真的有一个余额为2147483647的客户。在这种情况下,它们的最大余额将显示为空。

您使用的是什么数据库?这是SQL Server吗?您现在使用的替代方案甚至不应该按预期工作。您使用的是什么RDBMS?什么版本?@GordonLinoff-不,查询不好SQL中的“动态”是一件坏事,除非必要。您提供的答案是,根据一级近似,这是最好的方法。它简单、清晰,并且满足您的需要。你想用“更好”的方法来做这件事有什么原因吗?有什么问题需要解决吗?只是一个旁白;没有任何东西等于零。尝试在NULL=NULL时运行SELECT CASE,然后在1 ELSE 0结束时运行SELECT CASE,看看结果如何。此外,MIN会忽略任何空值,所以这就是为什么您的查询无法按预期工作(正如@Lamak指出的)?这是SQL Server吗?您现在使用的替代方案甚至不应该按预期工作。您使用的是什么RDBMS?什么版本?@GordonLinoff-不,查询不好SQL中的“动态”是一件坏事,除非必要。您提供的答案是,根据一级近似,这是最好的方法。它简单、清晰,并且满足您的需要。你想用“更好”的方法来做这件事有什么原因吗?有什么问题需要解决吗?只是一个旁白;没有任何东西等于零。尝试在NULL=NULL时运行SELECT CASE,然后在1 ELSE 0结束时运行SELECT CASE,看看结果如何。此外,MIN会忽略任何空值,这就是为什么您的查询无法按预期工作的原因(正如@Lamak所指出的)。更糟糕的是,子查询不会添加任何内容,而您会对整个列表进行排序以查找1个值。@David Manheim:子查询是满足此要求所必需的。我们只希望每个客户端有一行,并且不能在where子句中使用解析式。查询将为每个客户端返回一行,而不仅仅是一行。更糟糕的是:我没有检查过这种情况与各种分组解决方案的对比,但分析函数的性能往往优于它们。这是事实,但上面的陈述看起来是一个很好的解决方案,可以很好地执行。您使用的分析子查询比上面的
案例
/
分组依据
更昂贵,因为它必须对整个集合进行排序,先按计算列排序,然后按存储值排序-在计算每个值之前,无法进行优化。此外,除非在计算值上创建自定义索引,否则索引将不包括这一点。在上述问题中使用的语句中,如果它被
clientid
(然后可能被
balance
)索引,除了使用一次传递之外,还有一个好处。更糟糕的是,子查询将不添加任何内容,您可以对整个列表进行排序以查找1个值。@David Manheim:子查询对于该要求是必要的。我们只希望每个客户端有一行,并且不能在where子句中使用解析式。查询将为每个客户端返回一行,而不仅仅是一行。更糟糕的是:我没有检查过这种情况与各种分组解决方案的对比,但分析函数的性能往往优于它们。这是事实,但上面的陈述看起来是一个很好的解决方案,可以很好地执行。您使用的分析子查询比上面的
案例
/
分组依据
更昂贵,因为它必须对整个集合进行排序,先按计算列排序,然后按存储值排序-在计算每个值之前,无法进行优化。此外,除非在计算值上创建自定义索引,否则索引将不包括这一点。在上面问题中使用的语句中,如果它是由
clientid
索引的(然后可能是由
balance
),那么除了使用单个过程之外,还有一个好处。总之,看起来,我的查询比所有查询都好、简单。我希望我们可以使用任何SQL关键字来实现。总之,看起来,我的查询工作得很好,很简单。我希望我们可以使用任何SQL关键字来实现。