Проблема с запросом Sql Server с использованием BETWEEN, где с DATETIME

StackOverflow https://stackoverflow.com/questions/1461540

Вопрос

У меня есть хранимая процедура, которая перебирает месяцы финансового года и подсчитывает элементы каждого месяца.Я точно знаю, что здесь 176 элементов, но когда я запускаю это, общее количество возвращается 182.Я попытался удалить одну секунду из @EndDate, но тогда общее количество составило 165.Поэтому я либо считаю предметы дважды, либо не считаю их все.Может ли кто-нибудь помочь с тем, что я делаю здесь неправильно?Ниже приведена урезанная версия того, что я делаю:

DECLARE @Date DATETIME
DECLARE @EndDate DATETIME

SELECT @Date = CAST((@Year - 1) as VARCHAR) + '-07-01'
SELECT @EndDate = DATEADD(Month, 1, @Date)


DECLARE @Count INT
SELECT @Count = 0
WHILE @Count < 12

BEGIN

    SELECT 
        COUNT(yai.ID)
    FROM
        table_1    yai 
        INNER JOIN table_2 yat ON yai.ID = yat.ID 
    WHERE
        (yat.Date_Received BETWEEN CONVERT(VARCHAR, @Date, 101) AND CONVERT(VARCHAR, @EndDate, 101))  AND 
        yai.Pro_Type = @Value AND yat.Type = 'PC'

    SELECT @Count = @Count + 1
    SELECT @Date = DATEADD(MONTH, 1, @Date)
    SELECT @EndDate = DATEADD(MONTH, 1, @EndDate)

END
Это было полезно?

Решение

Из головы.

SELECT DATEPART(month, yat.Date) as month, COUNT(yai.ID)
FROM table_1 yai 
INNER JOIN table_2 yat ON yai.ID = yat.ID 
WHERE
    yai.Pro_Type = @Value AND yat.Type = 'PC' 
    AND DATEPART(year, yat.Date)=@Year
GROUP BY DATEPART(month, yat.Date)
ORDER BY DATEPART(month, yat.Date)

Другие советы

Промежуток включает в себя, поэтому ваше вычитание в 1 секунду должно быть там (или даже в день).Я предполагаю, что у некоторых яй нет соответствующего ят.

Редактировать:Ваш код фиктивный.Вы не можете выполнять сравнения, кроме равенства, с форматом 101.

Раньше я говорил забавные вещи, например, я точно знаю, что есть 50 элементов, а sql возвращает 60...

Я понял, что всегда ошибался!:)

Попробуйте удалить время из полей даты и времени:

DATEADD(д, DATEDIFF(д, 0, GetDate()), 0)

Не могли бы вы сделать это вместо этого?Следующий запрос даст вам количество, сгруппированное по месяцам.Если вы поместите это в представление, вы сможете выбрать его из представления и использовать предложениеwhere для фильтрации по интересующему вас году и месяцу.

select year(yat.Date_Received) as year, month(yat.Date_Received) as month, count(*) as count
    count(yai.ID)
from table_1 yai 
inner join table_2 yat on yai.ID = yat.ID 
where yai.Pro_Type = 'some_value' 
    and yat.Type = 'PC'
group by year(yat.Date_Received), month(yat.Date_Received)

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

 SELECT 
        COUNT(yai.ID)

к:

 SELECT 
     @Date,@EndDate,*

а затем посмотрите вывод и проверьте возвращаемые строки

Почему бы не преобразовать календарные месяцы в абсолютные целочисленные ссылки, например:

DECLARE @BeginDate datetime = '7/1/2008'
DECLARE @EndDate datetime = '6/30/2009'
--
-- Convert calendar months into an absoulte integer:
--
DECLARE @BeginMonth int = (DatePart(year, @BeginDate) * 12) + DatePart(month, @BeginDate)
DECLARE @EndMonth int = (DatePart(year, @EndDate) * 12) + DatePart(month, @EndDate)

SELECT COUNT(yai.ID)
FROM table_1 yai
INNER JOIN table_2 yat ON yai.ID = yat.ID
WHERE (DatePart(year, yat.Date_Received) * 12) + DatePart(month, yat.Date_Received) 
    BETWEEN @BeginMonth AND @EndMonth)
AND yai.Pro_Type = @Value
AND yat.Type = 'PC'

Я нашел этот вопрос, потому что у меня были проблемы с использованием строка даты в запросах с использованием «Между», и я использовал метаданные, мне помог мой коллега, поэтому я надеюсь, что это поможет и вам:

N'convert(date,[fld_myDate]) Between  convert(date,''01/01/2016'') AND convert(date,''08/26/2017'') '
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top