Pergunta

Eu tenho um procedimento armazenado que percorre os meses do ano fiscal e faz uma contagem para os itens de cada mês. Eu sei para um fato existem 176 itens, mas quando eu executar este ele retorna uma contagem total de 182. Eu tentei remover um segundo a partir @EndDate, mas então minha contagem total foi de 165. Então, eu estou tanto itens de contagem duas vezes, ou sem contar com todos eles. Alguém pode ajudar com o que estou fazendo de errado aqui? Abaixo está uma versão simplificada do que eu estou fazendo:

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
Foi útil?

Solução

A partir do topo da minha cabeça.

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)

Outras dicas

O meio é inclusiva, para que o seu 1 segundo subtrair deveria estar lá (ou mesmo um dia). Meu palpite é que alguns Yais não têm yat correspondente.

Edit: O código é falsa. Você não pode fazer outra coisa senão a igualdade comparações com o formato 101.

Eu costumava dizer coisas engraçadas que eu sei para um fato que há 50 itens e sql retornou 60 ...

Eu descobri que estava sempre errado! :)

Tente descascar a partir da data e hora campos:

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

Você não poderia fazer isso em vez disso? A consulta a seguir lhe dará conta agrupadas por mês. Se você colocar isso em um ponto de vista, você pode então selecionar a partir da vista e usar uma cláusula WHERE para filtrar pelo ano e mês que você está interessado.

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)

Este é um caso clássico de um loop desnecessário é o código SQL, mas se você quiser resolver isso com um loop, mudar a sua escolha no loop de:

 SELECT 
        COUNT(yai.ID)

para:

 SELECT 
     @Date,@EndDate,*

e, em seguida, olhar para a saída e verificar as linhas retornadas

Por que não converter os meses do calendário em referências absolutas inteiros como este:

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'

Eu encontrei esta pergunta, porque eu tinha problemas com o uso de Data de corda em consultas usando Entre e eu estava usando metadados , o meu colega de trabalho me ajudou, então eu espero que este ajuda-o demasiado:

N'convert(date,[fld_myDate]) Between  convert(date,''01/01/2016'') AND convert(date,''08/26/2017'') '
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top