Проблема с запросом к SQL Server с использованием BETWEEN, где с DATETIME - PullRequest
0 голосов
/ 22 сентября 2009

У меня есть хранимая процедура, которая проходит по месяцам финансового года и выполняет подсчет элементов в каждом месяце. Я точно знаю, что есть 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

Ответы [ 7 ]

1 голос
/ 22 сентября 2009

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

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

0 голосов
/ 26 августа 2017

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

N'convert(date,[fld_myDate]) Between  convert(date,''01/01/2016'') AND convert(date,''08/26/2017'') '
0 голосов
/ 22 сентября 2009

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

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'
0 голосов
/ 22 сентября 2009

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

 SELECT 
        COUNT(yai.ID)

до:

 SELECT 
     @Date,@EndDate,*

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

0 голосов
/ 22 сентября 2009

Не могли бы вы сделать это вместо этого? Следующий запрос даст вам количество сгруппированных по месяцам. Если вы поместите это в представление, вы можете затем выбрать его и использовать предложение 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)
0 голосов
/ 22 сентября 2009

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

Я узнал, что всегда был неправ! :)

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

DATEADD (d, DATEDIFF (d, 0, GetDate ()), 0)

0 голосов
/ 22 сентября 2009

С макушки головы.

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)
...