У меня есть столбец «Date_Sold» из таблицы в формате «Mon DD YYYY» Мне нужно разделить месяц и год из «Даты продажи» в формате «Пн ГГГГ» или «ГГГГ Пн».
например «Фев 2018» или «Фев 2018», Я знаю, как их разделить, используя
"Выбрать (left (Date_Sold, 3) + '' + Right (Date_Sold, 4)) из таблицы"
или "Выбрать (Right (Date_Sold, 4) + '' + left (Date_Sold, 3)) из таблицы",
но дело в том, что его нельзя упорядочить по реальной дате в этом формате, он либо по порядку
«2018 апр» -> «2018 авг» -> «2018 фев», или заказ «апр 2018» -> «декабрь 2017»,
Я тоже пробовал использовать
«Выберите Convert (varchar (12), year ([Date_Sold])) +» '+ Convert (varchar (12), Month ([Date_Sold])) из таблицы "
чтобы отобразить год и месяц в формате "2018 10", но также есть проблема, что
Октябрь 2018 «2018 10» наступит раньше, чем Февраль 2018 «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)
Вы всегда можете ORDER BY Date_Sold
, независимо от того, как вы форматируете дату в выбранном вами
date
, smalldatetime
, datetime
и datetime2
представляют собой хранится в виде чисел, а затем «переведены» в формат, который вы можете прочитать. Использование одного из этих типов данных - ЕДИНСТВЕННЫЙ способ правильно обрабатывать информацию о дате и времени. Любая попытка использовать строки в качестве даты / времени гарантированно потерпит неудачу. ОСТАНОВИТЕ использование строк. ИСПРАВИТЬ свои данные, используя соответствующий тип данных. Тогда у вас не будет этой проблемы, которую можно было бы избежать.
Я предлагаю вам следующее не как надежный способ сделать то, что вы просите, а как способ убедить вас, что хранить информацию о дате / времени в виде строк просто плохо.
Вам нужно «перевести» зависящие от языка названия месяцев в целые числа (и обратите внимание, что это нужно сделать для любого задействованного разговорного языка). Затем вам также нужно найти год, который, как я полагаю, является правильными 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
- это хранится в виде чисел.
Пожалуйста, сделайте себе огромное одолжение, не храните даты в формате МММ ДД ГГГГ.
На ваш вопрос нет точного решения. Проблема в первую очередь в том, что вы сохраняете дату как строку (nvarchar), а не как тип данных DateTime. Вы можете это сделать, но это излишне усложняет вашу жизнь, потому что вам нужно каким-то образом перестраивать все функции, которые уже реализованы в SQL. Кроме того, база данных не может гарантировать, что ожидаемые значения сохраняются приложением. В новой версии разработчик решает использовать «12-12-2018», а не «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;
Зачем хранить дату в виде строки?