Try this on for size:
DECLARE
@FromDate datetime,
@ToDate date; -- inclusive
SET @FromDate = DateAdd(month, DateDiff(month, 0, '20121118'), 0);
SET @ToDate = DateAdd(month, DateDiff(month, 0, '20121220') + 1, 0);
SELECT
Year = Year(S.date_time),
Month = Month(S.date_time),
QtyPerDay =
Sum(s.quantity) * 1.0
/ DateDiff(day, M.MonthStart, DateAdd(month, 1, M.MonthStart))
FROM
dbo.Sales S
INNER JOIN dbo.Items I
ON S.id_item = I.id_item
CROSS APPLY (
SELECT MonthStart = DateAdd(month, DateDiff(month, 0, S.date_time), 0)
) M
WHERE
I.kind = 'Kind of Item'
AND S.date_time >= @FromDate
AND S.date_time < @ToDate
GROUP BY
Year(S.date_time),
Month(S.date_time),
M.MonthStart
It will select any full month that is partially enclosed by the FromDate
and ToDate
. The * 1.0
part is required if the quantity
column is an integer, otherwise you will get an integer result instead of a decimal one.
Some stylistic notes:
Do NOT use string date conversion on a column to ensure you get whole days. This will completely prevent any index from being used, require more CPU, and furthermore is unclear (what does style 112 do again!?!?). To enclose full date periods, use what I showed in my query of DateCol >= StartDate
and DateCol < OneMoreThanEndDate
. Do a search for "sargable" to understand a very key concept here. A very safe and valuable general rule is to never put a column inside an expression if the condition can be rewritten to avoid it.
It is good that you're aliasing your tables, but you should use those aliases throughout the query for each column, as I did in my query. I recognize that the aliases V and A came from another language so they make sense there--just in general try to use aliases that match the table names.
Do include the schema name on your objects. Not doing so is not a huge no-no, but there are definite benefits and it is best practice.
When you ask a question it is helpful to explain all the logic so people don't have to guess or ask you--if you know (for example) that users can input mid-month dates but you need whole months then please indicate that in your question and state what needs to be done.
Giving the version of SQL server helps us zero in on the syntax required, as prior versions are less expressive. By telling us the version we can give you the best query possible.
Note: there is nothing wrong with putting the date calculation math in the query itself (instead of using SET to do it). But I figured you would be encoding this in a stored procedure and if so, using SET is just fine.