如何修改此 t-sql 查询以返回不同列名的最大值?

Posted

技术标签:

【中文标题】如何修改此 t-sql 查询以返回不同列名的最大值?【英文标题】:How to I modify this t-sql query to return the maximum value for different column names? 【发布时间】:2011-11-03 13:46:03 【问题描述】:

我有以下疑问:

SELECT
        [Rate],
        [RateMon],
        [RateTue],
        [RateWed],
        [RateThu],
        [RateFri],
        [RateSat],
        [RateSun]
    FROM
        [Room]
    WHERE
        Id=@Id

我不想返回所有列,而只想返回 Rate 和 RateMon、RateTue、RateWed、RateThu、RateFri、RateSat 和 RateSun 之间的最大值,但我很难,因为列名是不同。

现在返回的示例结果是:

100、400、400、400、400、600、600、600

其中 100 是速率,其他值对应于周一 - 周日,但在这种情况下我只想返回 100 和 600。

【问题讨论】:

请发布示例数据和结果。目前尚不清楚您在寻找什么。 SQL MAX of multiple columns? 的可能重复项 Function in SQL Server 2008 similar to GREATEST in mysql?的可能重复 我不会将此作为完全重复的内容关闭,因为 Mikael Eriksson 的回答提供了一些我自己和其他人可能不知道的有价值的东西。 @Xaisoft - 您是否点击了评论上方的重复链接? 【参考方案1】:
SELECT  [Rate],
        (SELECT MAX(T.[Rate])
         FROM (VALUES([RateMon]),
                     ([RateTue]),
                     ([RateWed]),
                     ([RateThu]),
                     ([RateFri]),
                     ([RateSat]),
                     ([RateSun])) AS T([Rate])
        ) AS MaxRate
FROM [Room]
WHERE Id=@Id

【讨论】:

最佳答案,因为它最简洁。 不确定我是否应该接受它,因为你来自瑞典,我是挪威人 :) 开个玩笑。 @Xaisoft - 好吧,我不会反对你:) @Andomar - 是的,从 SQL Server 2008 开始就可以做到这一点。对于以前的版本,您可以改用 select ... union all【参考方案2】:

您可以使用 union 子查询来反透视:

select  Rate
,       max(DayRate)
from    (
        select ID, Rate, RateMon as DayRate from Room
        union all
        select ID, Rate, RateTue from Room
        union all
        select ID, Rate, RateWed from Room
        union all
        ....
        ) as SubQuery
where   ID = @ID
group by
        Rate

【讨论】:

【参考方案3】:

你可以使用一些详细的东西,比如:

SELECT Rate,
  CASE 
    WHEN RateMon>=RateTue AND RateMon>=RateWed AND RateMon>=RateThu AND 
         RateMon>=RateFri AND RAteMon>=RateSat AND RateMon>=RateSun THEN RateMon
    WHEN RateTue>=RateMon AND RateTue>=RateWed AND RateTue>=RateThu AND 
         RateTue>=RateFri AND RateTue>=RateSat AND RateTue>=RateSun THEN RateTue
    WHEN RateWed>=RateMon AND RateWed>=RateTue AND RateWed>=RateThu AND 
         RateWed>=RateFri AND RateWed>=RateSat AND RateWed>=RateSun THEN RateWed
    WHEN RateThu>=RateMon AND RateThu>=RateTue AND RateThu>=RateWed AND 
         RateThu>=RateFri AND RateThu>=RateSat AND RateThu>=RateSun THEN RateThu
    WHEN RateFri>=RateMon AND RateFri>=RateTue AND RateFri>=RateWed AND 
         RateFri>=RateThu AND RateFri>=RateSat AND RateFri>=RateSun THEN RateFri
    WHEN RateSat>=RateMon AND RateSat>=RateTue AND RateSat>=RateWed AND 
         RateSat>=RateThu AND RateSat>=RateFri AND RateSat>=RateSun THEN RateSat
    WHEN RateSun>=RateMon AND RateSun>=RateTue AND RateSun>=RateWed AND 
         RateSun>=RateThu AND RateSun>=RateFri AND RateSun>=RateSat THEN RateSun
    END AS MaxRate 
FROM    
    [Room]    
WHERE    
    Id=@Id   

打字很多,但这是一种可能的答案。您还可以执行以下操作,这会稍微减少输入:

SELECT Rate, MAX(Rates.Rate) AS MaxRate
  FROM    
    [Room], 
      (SELECT RateMon AS Rate FROM [Room] WHERE Id=@Id UNION
       SELECT RateTue AS Rate FROM [Room] WHERE Id=@Id UNION
       SELECT RateWed AS Rate FROM [Room] WHERE Id=@Id UNION
       SELECT RateThu AS Rate FROM [Room] WHERE Id=@Id UNION
       SELECT RateFri AS Rate FROM [Room] WHERE Id=@Id UNION
       SELECT RateSat AS Rate FROM [Room] WHERE Id=@Id UNION
       SELECT RateSun AS Rate FROM [Room] WHERE Id=@Id)
     AS Rates
  WHERE    
    Id=@Id   

当然,正确的解决方案是规范化您的数据库并使其没有实际意义,因为简单的连接和聚合就足够了。

【讨论】:

哇,太棒了。谢谢,我会试一试。你会认为会有一些更简单的东西,比如给定一组列,返回最大值而不是所有这些案例逻辑。 MySql (GREATEST) 上有,但 SQL Server 上没有。 是的,我在另一篇文章中读到过。我想知道它是否会出现在 SQL Server 的未来版本中。

以上是关于如何修改此 t-sql 查询以返回不同列名的最大值?的主要内容,如果未能解决你的问题,请参考以下文章

数据库 t-sql 语句

如何修改我的T-SQL查询,以便输出基于2个不同时期出现两次或更多次的所有记录?

按 BigQuery 中列段的最大值返回列名

子查询 django 查询以从对象中获取最大的不同值并返回这些对象

如何制定 T-SQL 以避免主键约束?

T-SQL查询语句