views:

451

answers:

6

I have a Stored Procedure that loops through the months in the fiscal year and does a count for the items in each month. I know for a fact there are 176 items, but when I run this it returns a total count of 182. I tried removing one second from @EndDate, but then my total count was 165. So I'm either counting items twice, or not counting all of them. Can anyone help with what I'm doing wrong here? Below is a stripped down version of what I'm doing:

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
+1  A: 

The between is inclusive, so your 1-second subtract should be there (or even a day). My guess is that some yais have no corresponding yat.

Edit: Your code is bogus. You can't do comparisons other than equality with the format 101.

erikkallen
+1 for not being able to do comparisons with format 101, except equality.
Shannon Severance
Sorry, I didn't originally have the 101 conversion, that was just something I tried. I must have copied that code over instead of the actual one with the whole date
Jhorra
A: 

From the top of my head.

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)
Jonas Elfström
Of course you would need to sum() the count after that...
Parvenu74
This works except I need to do a fiscal year which starts in July.
Jhorra
This is close enough to what I need that I can modify it to make it work.
Jhorra
A: 

I used to say funny things like I know for a fact there is 50 items and sql returned 60...

I found out I was always wrong! :)

Try stripping the time from the date and time fields:

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

JonH
I know the number because I did a count. Also I have other report queries that break it down in other ways. All my numbers match up except for when I break it down by month.
Jhorra
A: 

Couldn't you do this instead? The following query will give you counts grouped by month. If you put this in a view, you can then select from the view and use a where clause to filter by the year and month you are interested in.

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)
RedFilter
A: 

this is a classic case of an unnecessary loop is SQL code, but if you want to solve this with a loop, change your select in the loop from:

 SELECT 
        COUNT(yai.ID)

to:

 SELECT 
     @Date,@EndDate,*

and then look at the output and check the rows returned

KM
A: 

Why not convert the calendar months into absolute integer references like this:

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'
Parvenu74