【问题标题】:How to get a MAX value from 3 columns in SQL Server stored procedures?如何从 SQL Server 存储过程中的 3 列中获取 MAX 值?
【发布时间】:2021-12-27 18:21:14
【问题描述】:

我正在开发一个使用 C# 和 SQL Server 数据库的项目。现在我必须编写一个存储过程,它需要从 3 个不同的列中获取一个 MAX 值。

我的代码如下所示:

CREATE PROCEDURE [dbo].[sp_GetClass]
    @surname nvarchar(50),
    @maxClass int OUT
AS
    SELECT @maxClass = MAX 
    FROM (VALUES (Programming), (Mathematics), (Physics)) 
    FROM MissLess 
    WHERE Surname LIKE '%' + @surname + '%'
GO

我收到第二个FROM 的错误,我不知道如何解决它。

这个想法是让它在输入姓氏时从这些列中获取最大值。当没有输入时(按回车键),它只显示所有姓氏中这 3 列的最大值。

对不起,如果格式或问题没有被问到,这是我在这里的第一篇文章。

编辑:@name 出错,应该是@surname;并且名称应该是姓氏。 编辑最终版:感谢您的出色帮助。我是所有这一切的超级新手,但这一切似乎都很有趣。差点就放弃了,但决定试一试。谢谢大家的回答!!!

【问题讨论】:

标签: c# sql-server


【解决方案1】:

您需要将所选行的这三个值放入存储过程中的表变量中,以便能够将MAX 应用于它们。

尝试这样的事情 - 我不知道这些值是什么 datatype - 只是假设 INT 在这里,根据需要进行调整:

CREATE PROCEDURE [dbo].[GetMaxValue]
    @surname NVARCHAR(50),
    @maxClass INT OUTPUT
AS
    DECLARE @IntTbl TABLE (AValue INT);
    
    INSERT INTO @IntTbl (AValue)
        SELECT Programming
        FROM MissLess 
        WHERE Name LIKE '%' + @name + '%'
        UNION ALL
        SELECT Mathematics
       FROM MissLess 
        WHERE Name LIKE '%' + @name + '%'
        UNION ALL
        SELECT Physics
        FROM MissLess 
        WHERE Name LIKE '%' + @name + '%';
        
    SELECT @maxClass = MAX(AValue)
    FROM @IntTbl;
GO

更新 - 好的,你要求它;-)

由于您的搜索条件可能匹配多行(至少您可能不能完全排除这种情况),您必须首先获取每列的 MAX(),基于搜索条件:

CREATE PROCEDURE [dbo].[GetMaxValue]
    @surname NVARCHAR(50),
    @maxClass INT OUTPUT
AS
    DECLARE @MaxMath INT, @MaxPhys INT, @MaxProgr INT;
    
    SELECT 
        @MaxMath = MAX(Mathematics),
        @MaxPhys = MAX(Physics),
        @MaxProgr = MAX(Programming)
    FROM 
        MissLess 
    WHERE 
        Name LIKE '%' + @name + '%';

    IF @MaxMath > @MaxPhys
    BEGIN       
        IF @MaxMath > @MaxProgr
            -- @MaxMath is bigger than both @MaxPhys AND @MaxProgr --> it's the overall MAX()
            SET @maxClass = @MaxMath;
        ELSE
            -- @MaxMath is bigger than @MaxPhys, but smaller than @MaxProgr 
            SET @maxClass = @MaxProgr;
    END
    ELSE BEGIN
        IF @MaxPhys > @MaxProgr
            -- @MaxPhys is bigger than both @MaxMath AND @MaxProgr --> it's the overall MAX()
            SET @maxClass = @MaxPhys;
        ELSE
            -- @MaxPhys is bigger than @MaxMath, but smaller than @MaxProgr 
            SET @maxClass = @MaxProgr;
    END;

    SELECT @maxClass = MAX(AValue)
    FROM @IntTbl;
GO

更新 #2:对于不使用表变量进行更新的更好、更简洁的解决方案 - 请参阅@AndrewCorrigan 的答案,使用CASE 表达式。

【讨论】:

  • 不可能全部放在同一张表里吗?是的,所有这些数据类型值都是 INT
  • 嵌套的 IF 语句会是什么样子?
  • 这种更新是荒谬的——case 语句比 if 块简单得多。
【解决方案2】:

你可以做 (Fiddle)

SELECT MAX(s) 
FROM MissLess      
CROSS APPLY (VALUES (Programming), (Mathematics), (Physics)) V(s)
WHERE Name LIKE '%' + @name + '%'

如果@name 谓词匹配多行,您将无法指出它来自哪一行

【讨论】:

    【解决方案3】:

    作为使用嵌套 CASE 语句的替代解决方案:

    SELECT @maxClass = MAX(CASE 
                                 WHEN Programming >= Mathematics
                                      AND Programming >= Physics
                                          THEN Programming
                                 WHEN Mathematics >= Physics
                                      AND Mathematics >= Programming
                                          THEN Mathematics
                                 ELSE Physics
                           END)
    FROM MissLess
    WHERE Surname LIKE '%' + @surname + '%';
    

    【讨论】:

    • 同意 - 这是一个更好、更简洁的解决方案,无需使用表变量 - 干杯!
    猜你喜欢
    • 2010-10-30
    • 2013-06-11
    • 2014-04-21
    • 2021-09-18
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    相关资源
    最近更新 更多