Лучше?Имейте дату в запросе всегда используйте дату в текущем году без обслуживания - PullRequest
1 голос
/ 31 июля 2010
SELECT Date_Received, DateAdd(Year, DateDiff(year, Cast('3/01/2010 12:00:00AM' as DateTime) , 
    GetDate())-1, Cast('3/01/2010 12:00:00AM' as DateTime)) as minimum_date
FROM [Volunteers].[dbo].[Applications]
WHERE Date_received >= DateAdd(Year, DateDiff(year, Cast('3/01/2010 12:00:00AM' as DateTime),
GetDate())-1, Cast('3/01/2010 12:00:00AM' as DateTime))

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

Мое текущее решение - ввести дату в запрос и использовать некоторые сложные DATEADD хитрости, чтобы получить текущий год (или предыдущий год) в дату, которую я использую в сравнении.Точный код выше.Есть ли для меня более чистый способ сделать это?

Спасибо

Редактировать

Бизнес-требование состоит в том, чтобы найти заявки, поданные в период с 3/01 по 7/31.

Мы проводим проверку данных, и это стоит нам денег за каждую проверку.Выявление заявок, поданных в течение этого периода времени, помогает нам определить, следует ли нам проводить полную, частичную проверку или проверку вообще не проводится.Мне также нужно будет проверить, относятся ли даты к предыдущему году.

Мы будем делать это каждый год, и нам нужно знать, были ли они в текущем году.Ведение запросов каждый год для обновления дат - это не то, что я хочу делать.

Поэтому я ищу хороший метод, позволяющий сохранять релевантность частей года в году без необходимости обновлять запрос или файл конфигурации..

Ответы [ 6 ]

3 голосов
/ 31 июля 2010

Старый трюк TSQL: приведите дату к строке в формате, который начинается с четырехзначного года, с использованием подстроки, чтобы взять первые четыре символа этого, приведите ее к дате.

На самом делепричина того, что это старый трюк TSQL, заключается в том, что, если я правильно помню, тогда не было функции year ().Учитывая, что теперь есть один, использование года (getdate ()), как ответили другие, вероятно, является лучшим ответом.

2 голосов
/ 31 июля 2010
 SELECT YEAR(GETDATE())

даст вам текущий год.

1 голос
/ 13 июля 2016

Функция TSQL возвращает четырехзначный год в зависимости от года.Это похоже на стандартные функции SQL YEAR [Thomas - nod] , которые можно настроить с помощью sp_configure для расширенных параметров, однако приведенный ниже код предоставляется в качестве основыТАМОЖЕННЫЕ требования и могут быть изменены по мере необходимости.например, вернуть как int, использовать со стандартными функциями DATETIME в SQL для достижения того, что необходимо.Например, при работе с «грязными» данными, которые мне пришлось перенести, я использовал их с функцией PATINDEX () для удаления нечисловых значений и т. д.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Andrew McLintock
-- Create date: 13 July 2016
-- Description: Return 4-digit YEAR
-- =============================================
/*
SELECT Staging.fn_4year('06')
SELECT Staging.fn_4year('56')
SELECT Staging.fn_4year('99')
SELECT Staging.fn_4year('1906')
SELECT Staging.fn_4year('2025')

*/
CREATE FUNCTION Staging.fn_4year
(
    @year_in varchar (4)
)
RETURNS varchar(4)
AS
BEGIN
    DECLARE @yeartmp int, @Retval varchar(4)
    SET @yeartmp = CAST(REPLACE(@year_in,' ','') AS INT)
    IF LEN(CAST(@yeartmp AS Varchar)) = 4
    BEGIN
        Return cast(@yeartmp as varchar(4))
    END
    IF LEN(@year_in) = 2
    BEGIN

        SET @Retval = CAST(iif(@yeartmp  > 49, @yeartmp + 1900, @yeartmp + 2000) AS varchar(4))
    END


    RETURN @Retval

END
GO
1 голос
/ 31 июля 2010

Если вам нужно выполнять запросы по месяцам и годам, вам также следует рассмотреть возможность преобразования этих свойств в постоянные вычисляемые поля:

ALTER TABLE dbo.Applications
    ADD DateReceivedMonth AS MONTH(Date_Received) PERSISTED

ALTER TABLE dbo.Applications
    ADD DateReceivedYear AS YEAR(Date_Received) PERSISTED

SQL Server теперь будет извлекать часть MONTH и YEAR вашего Date_Received и помещать их в два новых столбца. Они сохраняются, например, хранится вместе с данными вашей таблицы. SQL Server обеспечит их автоматическое обновление, например, если вы измените Date_Received, эти два новых столбца будут пересчитаны (но не для каждого SELECT).

Теперь ваши запросы могут быть намного проще:

SELECT (list of fields)
FROM dbo.Applications
WHERE DateReceivedYear = 2010 AND DateReceivedMonth BETWEEN 3 AND 7

Поскольку это постоянные поля, вы можете даже добавить к ним индекс, чтобы ускорить запросы к ним!

1 голос
/ 31 июля 2010

Есть ли причина, по которой вы не можете просто использовать функцию Year ?

Select Date_Received
        , Year(GetDate()) 
                - Year('3/01/2010 12:00:00AM') - 1 
                + Year('3/01/2010 12:00:00AM')
From [Volunteers].[dbo].[Applications]
Where Date_received >= ( Year(GetDate()) 
                        - Year('3/01/2010 12:00:00AM') - 1 
                        + Year('3/01/2080 12:00:00AM') )

Другим способом было бы использование выражения общей таблицы

With Years As
    (
    Select Year(GetDate()) As CurrentYear
        , Year('3/01/2010 12:00:00AM') As ParamYear
        , Year('3/01/2080 12:00:00AM') As BoundaryYear
    )
Select Date_Received
    , CurrentYear - Years.ParamYear - 1 + Years.ParamYear
From [Volunteers].[dbo].[Applications]
    Cross Join Years
Where Date_received >= ( Years.CurrentYear 
                            - Years.ParamYear - 1 + Years.BoundaryYear )
0 голосов
/ 31 июля 2010

Подумайте о том, чтобы сохранить набор datetime переменных, чтобы улучшить читаемость и удобство обслуживания. Я не уверен, что учел все ваши требования, особенно со ссылкой на «предыдущий год». Если это так же просто, как поиск заявлений, поданных между 3/01 и 7/31, то это должно сработать. Если вам необходимо определить те из них, которые были представлены с 1 августа (в прошлом году) по 28 февраля (в текущем году), это решение можно изменить в соответствии с требованиями.

DECLARE @Start smalldatetime, @End smalldatetime, @CurrYear char(4)
SELECT @CurrYear = YEAR(getdate())      

SELECT @Start = CAST( 'mar 1 ' + @CurrYear as smalldatetime),
        @End = CAST( 'jul 31 ' + @CurrYear  as smalldatetime)

 SELECT * 
 FROM Applications
 WHERE Date_Received
 BETWEEN @Start AND @End
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...