【问题标题】:SQL group by not getting top record没有获得最高记录的 SQL 组
【发布时间】:2013-01-05 12:04:48
【问题描述】:

下面是我表中的示例记录。

字段是 varchar, ToDate 包含两个空记录。 (不是数据库 NULL)

CustomerID  FromDate    ToDate
1           20120810    20120920
2           20120901    20120915
3           20120112    
4           20120815    
5           20120817    20120920
6           20120817    20120920

必须遵守以下规则:

  1. 按 ToDate 列中最远的日期排序。
  2. 当记录为空时,取当前日期+30 而不是空,
  3. 如果 ToDate 中的两个日期相同,则取 FromDate 中最远的日期。

所以对于上述记录样本,我需要输出为

CustomerID   FromDate   ToDate
3            20120112   20130221

因为客户 id 4 和 5 ToDate 是空的,所以我们考虑应该从 getdate() 函数中添加 30 天。所以 Todate 是相等的,所以我现在想按 FromDate 排序。

日期的输入是 20120810

select   top 1 customer_id, 
max(convert(datetime,Fromdate,101)) as Fromdate,
convert(datetime,(CASE WHEN Todate = '' THEN getdate() + 30 WHEN Todate != '' THEN Todate END),101) as Todate,
customer_id
FROM  dbo.sample_tbl (nolock)
 WHERE  customer_id = '1' 
 AND    Fromdate <= '20120810'
 AND    (CASE WHEN ToDate = '' THEN getdate() + 30 WHEN ToDate != '' THEN ToDate END) >= '20120810'
group by convert(datetime,(CASE WHEN ToDate = '' THEN getdate() + 30 WHEN ToDate != '' THEN ToDate END),101),customer_id
order by convert(datetime,(CASE WHEN ToDate = '' THEN getdate() + 30 WHEN ToDate != '' THEN ToDate END),101) desc

当前输出为

CustomerID   FromDate  ToDate
3            20120112  20130221

预计是

CustomerID   FromDate   ToDate
3            20120815   20130221

【问题讨论】:

  • 为什么将日期时间存储为 varchar?
  • 我一定很密集。你能强调一下“当前”和“预期”之间的区别吗?
  • @Damien_The_Unbeliever 我刚刚更新,你现在可以检查一下吗。
  • 您说“客户 ID 4 和 5 ToDate 为空”,但这不是您的示例数据所说的;这意味着我不太愿意尝试弄清楚您的要求到底是什么。
  • 我只是使用了todate desc,fromdate desc的顺序。并将getdate转换为varchar。现在问题已解决。

标签: sql sql-server


【解决方案1】:

在 SQLServer 2005+ 中

 ;WITH cte AS
 ( 
  SELECT CustomerID,         
         MAX(CAST(FromDate AS date)) OVER (PARTITION BY
         (CASE WHEN ToDate = '' THEN CAST(GETDATE() + 30 AS date) ELSE CAST(ToDate AS date) END
         )) AS FromDate,         
         CASE WHEN ToDate = '' THEN CAST(GETDATE() + 30 AS date) ELSE CAST(ToDate AS date) END AS ToDate
  FROM dbo.sample_tbl
  )
  SELECT TOP 1 CustomerID, MAX(FromDate) AS FromDate, ToDate
  FROM cte
  GROUP BY ToDate, CustomerID
  ORDER BY ToDate DESC

SQLFiddle上的演示

【讨论】:

    【解决方案2】:

    我认为你的代码太复杂和多余。 您应该创建一个 SQL 函数来获取 enddate。 调用这个函数getEndDate(String date)(我觉得你可以自己创建)

    您的查询可能是:

    select  CustomerID  ,FromDate  , getEndDate (ToDate) 
    from sample_tbl
    order by getEndDate (ToDate) desc, FromDate  desc  ;
    

    然后你占据第一行。

    【讨论】:

    • 你能提供那个功能吗?我不知道
    • 我个人使用 Oracle 而不是 sql server。在伪代码中应该是这样的: function getEndDate(String startdate, string endDate) begin if endDate = '' then return startDate + 30 else return endDate) END.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多