Можно ли заказать "Месяц Год" или "Год Месяц" в порядке реальной даты с использованием SQL - PullRequest
0 голосов
/ 27 октября 2018

У меня есть столбец «Date_Sold» из таблицы в формате «Пн ДД ГГГГ» Мне нужно разделить месяц и год от «Дата продажи» в формате «Пн ГГГГ» или «ГГГГ Пн»

например. «Фев 2018» или «Февраль 2018», Я знаю, как разделить их, используя

"Выбрать (слева (Date_Sold, 3) + '' + Right (Date_Sold, 4)) из таблицы"

или "Выбрать (вправо (Date_Sold, 4) + '' + left (Date_Sold, 3)) из таблицы" ,

но дело в том, что его нельзя заказать по реальной дате в этом формате, либо по порядку

"2018 апр" -> "2018 авг" -> "2018 фев", или заказ "Апр 2018" -> "Дек 2017",

Я также пытался использовать

"Выбрать Преобразование (varchar (12), год ([Date_Sold])) + '' + Преобразовать (varchar (12), Месяц ([Date_Sold])) из таблицы "

для отображения года и месяца в формате "2018 10", но это также имеет проблему, которая

Октябрь 2018 "2018 10" наступит раньше, чем Февраль 2018 "2018 2"

Можно ли использовать SQL для отображения и заказа "Месяц Год" или "Год Месяц" в реальной дате?

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

Точного решения вашего вопроса не существует.Проблема в первую очередь в том, что вы сохраняете дату как строку (nvarchar), а не как тип данных DateTime .Вы можете сделать это, но это делает вашу жизнь излишне трудной, потому что вам нужно каким-то образом перестроить все функции, которые SQL уже реализовал.Кроме того, база данных не может гарантировать, что ожидаемые значения сохраняются приложением.В новой версии разработчик решает использовать «12-12-2018», а не «12.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;
0 голосов
/ 27 октября 2018

Я предлагаю вам следующий не как надежный метод выполнения того, что вы просите, а как способ убедить вас, что хранить информацию о дате / времени в виде строк просто плохо.

Вам необходимо «перевести» языковые названия месяцев в целые числа (и учтите, что это необходимо сделать для любого разговорного языка). Тогда вам также нужно найти год, который, я полагаю, является правильным 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.

...