make yourself a tally table (in my example tblNumbers) containing a single integer field (in my example intNum) indexed unique. folk are unlikely to stay forever, so you might as well populate this table manually with 1,2,3,4,5,6.....to something significantly more than the maximum likely stay in days.
what does that do for you?
try this (replacing @dtIn, @dtOut with your dates - i used 10 ... 20 August)
Code:
SELECT n.intNum, DATEADD(d,n.intNum -1,@dtIn) AS Night
FROM tblNumbers AS n
WHERE n.intNum <= DATEDIFF(d,@dtIn,@dtOut)
Result:
intNum Night
----------- -----------------------
1 2010-08-10 00:00:00.000
2 2010-08-11 00:00:00.000
3 2010-08-12 00:00:00.000
4 2010-08-13 00:00:00.000
5 2010-08-14 00:00:00.000
6 2010-08-15 00:00:00.000
7 2010-08-16 00:00:00.000
8 2010-08-17 00:00:00.000
9 2010-08-18 00:00:00.000
10 2010-08-19 00:00:00.000
(10 row(s) affected)
where next?
i made a table similar to yours (tblPrice) with fields dtStart, dtEnd, mRate
and populated it with a rate change from 200 to 150 on 16th August.
try this (again replacing @dtIn, @dtOut with your dates)
Code:
SELECT p.mRate
FROM tblPrice AS p
RIGHT JOIN (
SELECT DATEADD(d,n.intNum -1,@dtIn) AS Night
FROM tblNumbers AS n
WHERE n.intNum <= DATEDIFF(d,@dtIn,@dtOut)
) AS x
ON x.Night >= p.dtStart AND x.Night <= p.dtEnd
Result:
mRate
---------------------
200.00
200.00
200.00
200.00
200.00
200.00
150.00
150.00
150.00
150.00
(10 row(s) affected)
and using
SELECT SUM(p.mRate) instead takes you where you want to go.
i don't have Access on this machine to check, but the syntax shouldn't be too far wrong. this tally table route will be **FAR** faster than any loops you can think of.
google 'sqlservercentral tally table' for some background (including ways to auto-populate your tally table).
izy