【问题标题】:Is it possible order "Month Year" or "Year Month" in real date order using SQL是否可以使用 SQL 以实际日期顺序订购“月年”或“年月”
【发布时间】:2018-10-26 21:00:39
【问题描述】:

我在表格中有一列“Date_Sold”,格式为“Mon DD YYYY” 我需要以“Mon YYYY”或“YYYY Mon”的格式从“Date Sold”中提取月份和年份

例如“2018 年 2 月”或“2018 年 2 月”, 我知道如何使用

来分割它们

“从表中选择 (left(Date_Sold, 3) + ' ' + Right(Date_Sold,4))”

或“从表中选择(Right(Date_Sold,4) + ' ' + left(Date_Sold, 3))”,

但问题是,它不能以这种格式按实际日期排序,它要么按顺序

“2018 年 4 月”->“2018 年 8 月”->“2018 年 2 月”, 或订购“2018 年 4 月”->“2017 年 12 月”,

我也试过用

"Select Convert(varchar(12), year([Date_Sold])) + ' ' + Convert(varchar(12), Month([Date_Sold])) from Table"

将年份和月份显示为“2018 10”格式, 但它也有问题

2018 年 10 月 “2018 10” 将早于 2018 年 2 月 “2018 年 2”

是否可以使用SQL来显示和排序“年月”或“年月”的真实日期?

【问题讨论】:

  • 为什么要将日期存储为字符串?
  • 对于工作需求,我需要以实际日期的“Mon Year”或“Year Mon”作为一个维度来显示历史趋势
  • 不要这样做,哦不要这样做!如您所见,您让一切变得更加困难。
  • 1.更改Convert(varchar(12), Month([Date_Sold])) => right('0'+Convert(varchar(12), Month([Date_Sold])),2)
  • 2. select convert(nvarchar(6),[Date_Sold],112)

标签: sql sql-server sorting date sql-order-by


【解决方案1】:

我向您提供以下内容并不是一种可靠的方法来满足您的要求,而是一种让您相信将日期/时间信息存储为字符串的方式是不好的。

您需要将依赖于语言的月份名称“翻译”为整数(请注意,这需要对涉及的任何口语进行)。然后你还需要找到年份,我认为它是正确的 4 个字符。使用datefromparts(),您可以得到一个真实/正确的日期进行排序(或者您只需使用order by y, m,但我也想让您知道如何获得真实日期。)

CREATE TABLE mytable(
   Date_Sold varchar(20)
);
INSERT INTO mytable(Date_Sold) VALUES ('Jan 17 2018');
INSERT INTO mytable(Date_Sold) VALUES ('Feb 14 2018');
INSERT INTO mytable(Date_Sold) VALUES ('Mar 13 2018');
INSERT INTO mytable(Date_Sold) VALUES ('Sep 10 2018');

select
*
from mytable
cross apply (
    select case
             when patindex('%jan%',date_sold) > 0 then 1 
             when patindex('%feb%',date_sold) > 0 then 2
             when patindex('%mar%',date_sold) > 0 then 3 
             when patindex('%apr%',date_sold) > 0 then 4 
             when patindex('%may%',date_sold) > 0 then 5 
             when patindex('%jun%',date_sold) > 0 then 6 
             when patindex('%jul%',date_sold) > 0 then 7 
             when patindex('%aug%',date_sold) > 0 then 8 
             when patindex('%sep%',date_sold) > 0 then 9 
             when patindex('%oct%',date_sold) > 0 then 10 
             when patindex('%nov%',date_sold) > 0 then 11 
             when patindex('%dec%',date_sold) > 0 then 12 
           end 
        , try_cast(right(date_sold,4) as integer)
    ) ca (m, y)
order by datefromparts(y,m,1)

请注意,日期排序需要数字。处理日期/时间需要大量的数字处理(例如计算“上个月”、“下周”、“本财政年度”和其他十亿)。这就是为什么date、smalldatetime、datetime 和datetime2存储为数字。

请帮自己一个大忙,不要以 MMM DD YYYY 格式存储日期。

【讨论】:

    【解决方案2】:

    您的问题没有确切的解决方案。问题主要在于您将日期保存为字符串 (nvarchar) 而不是 DateTime 数据类型。您可以这样做,但这会使您的生活变得不必要地困难,因为您必须以某种方式重建 SQL 已经实现的所有功能。此外,数据库无法确保应用程序存储预期值。在新版本中,开发者决定使用“12-12-2018”而不是“Dec 12 2018”,然后呢?

    为了避免不准确和不确定的陷阱,建议采用以下方法。

    CREATE TABLE [dbo].[FactSales](
        [SalesOrderNumber] [int] NOT NULL,
        [ItemNumber] [int] NOT NULL,
        [OrderQuantity] [int] NOT NULL,
        [SalesAmount] [money] NOT NULL,
        [SalesDate] [datetime] NOT NULL,
     CONSTRAINT [PK_FactSales] PRIMARY KEY CLUSTERED 
    (
        [SalesOrderNumber] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    INSERT INTO [dbo].[FactSales]
               ([SalesOrderNumber]
               ,[ItemNumber]
               ,[OrderQuantity]
               ,[SalesAmount]
               ,[SalesDate])
         VALUES
               (1,1000,1,140.10,'2018-06-30 10:34:09'),
               (2,1005,10,40.10,'2018-07-30 1:34:09'),
               (3,1005,12,150.10,'2018-07-30 11:34:09'),
               (4,1009,3,199.10,'2018-08-30 11:34:09')
    

    您将销售日期存储为 DateTime。为了进一步分析、报告或在您的数据仓库中使用,您可以使用 SQL 函数提取月份和年份:

    SELECT *, datepart(month, SalesDate) as SalesMonth, datepart(year, SalesDate) as SalesYear From FactSales;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多