【问题标题】:The max value of several columns (date and cost relationship)几列的最大值(日期和成本关系)
【发布时间】:2010-01-03 04:03:52
【问题描述】:

如何返回几列的最大值(日期和成本关系)?

TableName [ID, Date1, Cost1, Date2, Cost2, Date3, Cost3]

我需要返回如下内容:[ID, Most Recent Date, Cost]


我需要返回如下内容:

  • 身份证
  • 最近日期
  • 与日期相关的成本(如果最近的日期是 Date1 那么成本就是 Cost1)

我需要使用另一个表 - BackupTableName:

  • 身份证
  • 日期1
  • 成本1
  • 日期2
  • 成本2
  • 日期3
  • 成本3

...并在 TableName 中的 Cost1、Cost2 和 Cost3 为空的情况下使用其数据。

【问题讨论】:

  • 您好 Chandra Patni,我使用的是 SQL Server 2005,所以最好的不能正常工作。我需要返回类似这样的信息:[ID,最近日期,与日期相关的成本](如果最近的日期是 Date1,那么成本是 Cost1)谢谢你,John
  • 这个数据模型越来越好......

标签: sql sql-server sql-server-2005 aggregate


【解决方案1】:
SELECT ID,
    CASE
        WHEN Date1>Date2 AND Date1>Date3 THEN Date1
        WHEN Date2>Date1 AND Date2>Date3 THEN Date2
        ELSE Date3
    END AS "Most Recent Date",
    CASE
        WHEN Date1>Date2 AND Date1>Date3 THEN Cost1
        WHEN Date2>Date1 AND Date2>Date3 THEN Cost2
        ELSE Cost3
    END AS Cost
FROM TableName;

‘Date1’...‘Date2’...‘Date3’是一种模式气味。考虑规范化为单独的多对一表。

预计到达时间:

TableName中Cost1、Cost2、Cost3为空的情况。

你也有空值吗?好吧,这变得非常不愉快。您需要防止空值,例如:

    CASE
        WHEN Date1>COALESCE(Date2, 0) AND Date1>COALESCE(Date3, 0) THEN Date1
        WHEN Date2>COALESCE(Date1, 0) AND Date2>COALESCE(Date3, 0) THEN Date2
        ELSE Date3
    END AS "Most Recent Date",

(在日期选择位和成本选择位中。假设成本通常总是高于 0。)

我需要使用另一个表:BackupTableName [ID, Date1, Cost1, Date2, Cost2, Date3, Cost3] 并使用它的数据

嗯...这是可能的,但您的模型现在看起来非常不稳定。

SELECT t0.ID,
    CASE
        WHEN t0.Date1>COALESCE(t0.Date2, 0) AND t0.Date1>COALESCE(t0.Date3, 0) THEN t0.Date1
        WHEN t0.Date2>COALESCE(t0.Date1, 0) AND t0.Date2>COALESCE(t0.Date3, 0) THEN t0.Date2
        WHEN t0.Date3>COALESCE(t0.Date1, 0) AND t0.Date3>COALESCE(t0.Date1, 0) THEN t0.Date3
        WHEN t1.Date1>COALESCE(t1.Date2, 0) AND t1.Date1>COALESCE(t1.Date3, 0) THEN t1.Date1
        WHEN t1.Date2>COALESCE(t1.Date1, 0) AND t1.Date2>COALESCE(t1.Date3, 0) THEN t1.Date2
        WHEN t1.Date3>COALESCE(t1.Date1, 0) AND t1.Date3>COALESCE(t1.Date1, 0) THEN t1.Date3
    END AS "Most Recent Date",
    -- the same thing all over again for the cost selector
FROM TableName AS t0
LEFT JOIN BackupTableName AS t1 ON t0.ID=t1.ID;

如果在你的能力范围内,你需要normalise这些表,因为你现在拥有的数据模型基本上已经被破坏了。

【讨论】:

  • 对于 SQLServer,投票解决方案提供了 bobince。特别是针对多对一表的建议,因为您的数据违反了 1NF。
  • +1 是的,感谢您回答给定的问题,建议避免“元数据 Tribbles”反模式。
【解决方案2】:

如果你的数据库支持,你可以使用greatest函数

select ID, greatest(Date1, Date2, Date3) as recent_date, 
           greatest(Cost1, Cost2, Cost3) as priceless from Table

【讨论】:

  • 遗憾的是 MySQL、Oracle、Postgres 支持 GREATEST 但 SQL Server 不支持 :(
  • 嗨 bobince,非常感谢您的帮助和建议。现在,我的问题有点复杂。我需要使用另一个表:BackupTableName [ID, Date1, Cost1, Date2, Cost2, Date3, Cost3] 并在 TableName 中的 Cost1、Cost2 和 Cost3 为空的情况下使用它的数据。如果您也可以帮助我,请告诉我。再次感谢你,约翰
  • 嗨 bobince,查询非常完美!非常感谢您的帮助和建议。约翰
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 2015-01-27
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多