【问题标题】:Sort Asc and desc in the same column在同一列中排序 Asc 和 desc
【发布时间】:2021-02-08 11:39:05
【问题描述】:

我在表中有一个日期列,我想创建一个 SELECT 查询,该查询的结果顺序将是所有大于或等于今天日期的日期first 并且 order 应该是 ASC ,并且所有小于今天日期的日期都将是 second 并且 order 将是 DESC

顺序应该是这样的:

注释:

  1. 在以下列表中,日期格式为 YYYY-MM-DD
  2. 今天的日期是 2021 年 2 月 8 日
  3. 我的日期数据类型是date
2021-02-08
2021-02-09
2021-05-18
2022-06-29<----This is the last bigger and equal then today
2021-02-07<----This is the first smaller then today
2021-02-06
2021-01-03
2020-12-06
2020-10-08
    ;with cte
    as
    (
    select 
        CustomrId
        ,CustomrName
        ,SubscriptionDate
        ,SubscriptionInDays
        ,datediff(day, dateadd(DAY, SubscriptionInDays, SubscriptionDate), CAST(GETDATE() AS Date )) as DaysToEnd
    from 
        TBL 
)
select 
    CustomrId
    ,CustomrName
    ,SubscriptionDate
    ,SubscriptionInDays
    ,-iif(DaysToEnd > 0, 0 ,DaysToEnd) as DaysToEnd
from 
    cte
order by 
        case 
            when DaysToEnd = 0 then 0
            when DaysToEnd > 0 then 1 
        end
        ,DaysToEnd



In this approach this is the result order I'm getting:
2021-02-08
2021-02-09
2021-05-18
2022-06-29<----This is the last bigger and equal then today
2020-10-08
2020-12-06
2021-01-03
2021-02-06
2021-02-07<----This is the first smaller then today

【问题讨论】:

  • "我的日期格式是 YYYY-MM-DD" 日期和时间数据类型没有格式,它们是二进制值。如果您的数据正在以“格式”存储,则它的定义不是date,很可能是varchar(一个主要的设计缺陷)。至于问题,您尝试过什么?看起来您只需要几个 CASE 表达式。
  • 我的意思是,在我在帖子中写的列表中,日期以 YYYY-MM-DD 格式书写。 (我会编辑帖子)
  • 谢谢,但您没有包括您的尝试。请这样做,并解释为什么它们不起作用。

标签: sql-server tsql sql-order-by


【解决方案1】:

你需要条件排序:

SELECT *
FROM tablename
ORDER BY 
  CASE WHEN datecolumn >= CONVERT(DATE, GETDATE()) THEN 1 ELSE 2 END,
  ABS(DATEDIFF(day, CONVERT(DATE, GETDATE()), datecolumn))

请参阅demo
结果:

datecolumn
2021-02-08
2021-02-09
2021-05-18
2022-06-29
2021-02-07
2021-02-06
2021-01-03
2020-12-06
2020-10-08

【讨论】:

  • 优雅的解决方案!它可以通过强制Sign:select TN.* from TableName as TN cross apply ( select DateDiff( day, Cast( GetDate() as Date ), DateColumn) as Delta ) as Diff( Delta ) order by -( Sign( Delta ) - 1 ) / 2, Abs( Delta ); 来混淆。在Sign 周围的额外摆弄是为了让当前日期落入正确的一半。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
  • 1970-01-01
  • 2017-12-17
  • 2023-03-24
  • 1970-01-01
  • 2015-03-05
  • 2018-05-26
相关资源
最近更新 更多