是否可以使用SQL以实际日期顺序订购“月年”或“年月”

时间:2018-10-26 21:00:40

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

我在表格中有一列“ Date_Sold”,格式为“ Mon DD YYYY” 我需要以“星期一YYYY”或“ YYYY星期一”的格式从“出售日期”中分出月份和年份

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

“从表中选择(左(Date_Sold,3)+''+右(Date_Sold,4))“

“从表中选择(右(Date_Sold,4)+''+左(Date_Sold,3))“

但是事实是,它不能以这种格式按实际日期排序

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

我也尝试使用

“从表中选择Convert(varchar(12),year([Date_Sold]))+''+ Convert(varchar(12),Month([Date_Sold]))

以“ 2018 10”格式显示年份和月份, 但也有一个问题

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

是否可以使用SQL实时显示和订购“月年”或“年月”?

2 个答案:

答案 0 :(得分:0)

我为您提供的以下信息并不是一种可靠的方法来执行您的要求,而是一种说服您将日期/时间信息存储为字符串的方法。

您需要将与语言相关的月份名称“翻译”为整数(请注意,涉及的所有口语都需要这样做)。然后,您还需要定位年份,我认为这是正确的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)

请注意,日期排序需要数字。处理日期/时间需要进行大量的数字运算(例如,计算“上个月”,“下周”,“本会计年度”以及其他十亿个数字)。这就是为什么以数字形式存储datesmalldatetimedatetimedatetime2 的原因。

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

答案 1 :(得分:0)

您的问题没有确切的解决方案。问题主要是您将日期另存为字符串(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;