【问题标题】:Function in SQL Server 2008 similar to GREATEST in mysql?SQL Server 2008 中的功能类似于 mysql 中的 GREATEST?
【发布时间】:2011-01-18 15:22:41
【问题描述】:

我想求多列的最大值。

MySQL 支持 GREATEST 函数,但 SQL Server 不支持。

SQL Server 2008 中是否有类似的功能?

【问题讨论】:

标签: sql sql-server sql-server-2008


【解决方案1】:

SQL Server 2008 中没有,但这些函数 are/will be available finally in SQL Server(可能是 SQL Server 2022)

现在,GREATEST 和 LEAST T-SQL 函数在 Azure SQL 数据库以及 Azure Synapse Analytics(无服务器 仅限 SQL 池)和 Azure SQL 托管实例。

这些函数也将在即将发布的 SQL 版本中提供 服务器。

对于以前的版本,您可以使用子查询可以访问外部查询中的列的事实,以便您可以添加子查询从这些的联合中选择max

SELECT *, 
      (SELECT MAX(c) FROM (VALUES(number),(status)) T (c)) AS Greatest
FROM master..spt_values

或者对于 SQL Server 2000/2005

SELECT *, 
      (SELECT MAX(c) FROM 
                    (SELECT number AS c 
                     UNION ALL 
                     SELECT status) T) AS GreatestNumberOrStatus
FROM master..spt_values

【讨论】:

  • +1,虽然它比一堆CASE 语句效率低。
  • 同意,但如果列数很大,它也不是灾难性的低效且更容易维护。
  • “您可以添加子查询 UNION ALL 将感兴趣的列作为派生表”- 可以使用 CTE 执行相同操作。
  • @oneday - 我不知道怎么做?派生表仅包含当前行的值。
  • ++ 用于 2008 年的 VALUES() 语法
【解决方案2】:

为此,我创建了一个标量函数,如下所示:

CREATE FUNCTION [dbo].[MaxOrNull](@val1 int, @val2 int)
returns int
as
begin
    if @val1 >= @val2 RETURN @val1
    if @val1 < @val2 RETURN @val2

    RETURN NULL
end

这是最优雅的解决方案,可以在 SQL 代码的任何地方使用。

【讨论】:

  • 我不确定我以前是否曾在同一句话中看到过标量函数和优雅这两个词!例如,OP 如何使用它来计算 GREATEST(col1,col2,col3,col4,col5,col6)?它不需要很多排列吗?编辑:实际上,您当然可以嵌套调用,在这种情况下,排列增长是您想要跨列排序的不同场景。
  • 好吧@Martin,有时需要转变观点才能看到优雅。到处都是硬编码凌乱的SQL,就像上面最佳答案^^^中的详细答案一样,简直是疯了。你回答了你的第二个问题。在 C++ 或 C# 中也是如此。
  • 我想给你+1。但这是我在 SQL 2008 之前使用的方法,优先于嵌套的 select-max-union。我平时用的函数比较简洁create function dbo.greater(@a int, @b int) returns int as begin return case when @a &gt;= isnull(@b,@a) then @a else @b end end
  • 我喜欢你的 CASE 版本。很整洁。 +1
【解决方案3】:

我会推荐以下解决方案:

SELECT (CASE WHEN t.createdt < t.changedt THEN t.changedt ELSE t.created END) AS ChgDate
  FROM table t

【讨论】:

    【解决方案4】:

    一个可能的解决方案:

    Create FUNCTION [dbo].[MaxOf]
        (
          @val1 INT =0,
          @val2 INT=0 ,
          @val3 INT =0,
          @val4 INT =0,
          @val5 INT =0,
          @val6 INT =0,
          @val7 INT =0,
          @val8 INT =0,
          @val9 INT =0,
          @val10 INT =0,
          @val11 INT =0,
          @val12 INT =0,
          @val13 INT =0,
          @val14 INT =0,
          @val15 INT =0,
          @val16 INT =0,
          @val17 INT =0,
          @val18 INT =0,
          @val19 INT =0,
          @val20 INT  =0)
          --OUTPUT 
         RETURNS INT  WITH SCHEMABINDING
    AS  
       BEGIN
            DECLARE  @MAX AS INT ;
            SET @MAX=0
            IF isnull(@val1,0)> isnull(@MAX,0) SET @MAX=isnull(@val1,0) 
            IF isnull(@val2,0)> isnull(@MAX,0) SET @MAX=isnull(@val2,0) 
            IF isnull(@val3,0)> isnull(@MAX,0) SET @MAX=isnull(@val3,0) 
            IF isnull(@val4,0)> isnull(@MAX,0) SET @MAX=isnull(@val4,0) 
            IF isnull(@val5,0)> isnull(@MAX,0) SET @MAX=isnull(@val5,0) 
            IF isnull(@val6,0)> isnull(@MAX,0) SET @MAX=isnull(@val6,0) 
            IF isnull(@val7,0)> isnull(@MAX,0) SET @MAX=isnull(@val7,0) 
            IF isnull(@val8,0)> isnull(@MAX,0) SET @MAX=isnull(@val8,0) 
            IF isnull(@val9,0)> isnull(@MAX,0) SET @MAX=isnull(@val9,0) 
            IF isnull(@val10,0)> isnull(@MAX,0) SET @MAX=isnull(@val10,0) 
            IF isnull(@val11,0)> isnull(@MAX,0) SET @MAX=isnull(@val11,0) 
            IF isnull(@val12,0)> isnull(@MAX,0) SET @MAX=isnull(@val12,0) 
            IF isnull(@val13,0)> isnull(@MAX,0) SET @MAX=isnull(@val13,0) 
            IF isnull(@val14,0)> isnull(@MAX,0) SET @MAX=isnull(@val14,0) 
            IF isnull(@val15,0)> isnull(@MAX,0) SET @MAX=isnull(@val15,0) 
            IF isnull(@val16,0)> isnull(@MAX,0) SET @MAX=isnull(@val16,0) 
            IF isnull(@val17,0)> isnull(@MAX,0) SET @MAX=isnull(@val17,0) 
            IF isnull(@val18,0)> isnull(@MAX,0) SET @MAX=isnull(@val18,0) 
            IF isnull(@val19,0)> isnull(@MAX,0) SET @MAX=isnull(@val19,0) 
            IF isnull(@val20,0)> isnull(@MAX,0) SET @MAX=isnull(@val20,0) 
    
            RETURN @MAX ;
        END
    

    电话将是

    SELECT dbo.MaxOf (2,3,4,0,0,0,0,200,8,0,0,0,0,0,0,0,0,0,0,0)
    

    【讨论】:

      【解决方案5】:

      尝试改用TOPMAX

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-22
        • 1970-01-01
        • 2014-11-27
        • 1970-01-01
        • 2010-11-14
        • 1970-01-01
        相关资源
        最近更新 更多