2016-10-24 1 views
0

Как создать запрос sql-сервера, который игнорирует 29 февраля в не-високосный год и включает 29 февраля в високосный год. (Предположим, у меня есть столбец в таблице с датами от 2000-01-01 до 2016-12-31, например)Как выбрать даты записи из таблицы с прыжком и без високосного года?

На данный момент у меня есть это, но он полностью удаляет високосные годы.

SELECT uid, CONVERT(DATE,CAST(DATEPART(yyyy,day) AS VARCHAR(4))+'-'+ 
       CAST([Month] AS VARCHAR(2))+'-'+ 
       CAST(29 AS VARCHAR(2))) AS code_date, [29] AS code FROM [data] 
       WHERE DATEPART(mm,day) <> 2 AND NOT (ISDATE(CAST(DATEPART(yyyy,day) AS char(4)) + '0229') = 1) 

Однако я хочу только удалить все 29 февраля каждый год, кроме високосного года.

+0

нужный вам список дат? или знаете, если год прыжок или нет? –

+2

Пожалуйста, объясните, что вы пытаетесь выполнить. Тип данных «date» не поддерживает 29 февраля в непиковые годы, поэтому я могу понять, что вы действительно хотите сделать. –

+0

Даты в моей базе данных не чисты, и они включают 28 и 29 для всех прыжков и не-високосных годов. Я хочу выбрать только даты, которые включают все годы, но игнорирует 29,30 и 31 для не-високосного года и 30 и 31 для високосного года. – Tee

ответ

0

Я, наконец, понял, и вот ответ

SELECT uid, CONVERT(DATE,CAST(DATEPART(yyyy,mydate) AS VARCHAR(4))+'-'+ 
       CAST([Month] AS VARCHAR(2))+'-'+ 
       CAST(29 AS VARCHAR(2))) AS code_date, [29] AS code FROM [data] 
       WHERE DATEPART(mm,mydate) <> 2 OR (ISDATE(CAST(DATEPART(yyyy,mydate) AS char(4)) + '0229') = 1) 

Это выбирается только 29 февраля, если только дата является високосным годом и исключает 29 февраля в не високосный год.

+0

Вы рассматривали возможность фиксации данных в базе данных? Почему у вас есть строки в базе данных, которые по дизайну неправильны и их нужно игнорировать? –

+0

Данные были импортированы в базу данных из другого источника (excel) и включают неправильные даты – Tee

0

SQL Server знает, что годы были високосными :)

select isdate('2/29/2015') 
select isdate('2/29/2016') 

Возвращаемое значение IsDate зависит от параметров, установленных SET DATEFORMAT, SET LANGUAGE и настройка по умолчанию язык Сервер Вариант конфигурации.

Here является функцией, чтобы сказать вам, если год високосный год:

CREATE FUNCTION dbo.IsLeapYear (@year INT) 
RETURNS INT 
AS 
BEGIN 
RETURN(IIF(DATEPART(dd,(EOMONTH(CONCAT(@year,'0201')))) = 29,1,0)) 
END 
GO 

Вы можете просто создать таблицу календаря или использовать его в КТР, как отметил HERE:

--notice 2/29/2016 but no 2/29/2015 
DECLARE @MinDate DATE = '20150201', 
     @MaxDate DATE = '20160306'; 

SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1) 
     Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate) 
FROM sys.all_objects a 
     CROSS JOIN sys.all_objects b;