0

Table Pricing

enter image description here

What i want, is to provide a start_date & an end_date in order to get the price_per_day for each day between those 2 dates.

For example if i set as a start_date = 2015-05-30 & end_date = 2015-06-02, the desired output is

2015-05-30 | 24.00

2015-05-31 | 24.00

2015-06-01 | 27.00

2015-06-02 | 27.00

UPDATE:

Even if this output would be ok for me

24.00

24.00

27.00

27.00

Makis
  • 1,214
  • 3
  • 16
  • 40
  • 2
    A calendar table with all dates could be useful. – jarlh Nov 02 '15 at 08:37
  • @jarlh Unfortunately this is not an option for me, i have to work in an existing db.! – Makis Nov 02 '15 at 08:38
  • Then you'll have to generate one to "explode" the range of dates. If you have a numbers table you could use that, otherwise try one of the many tricks out there like recursive CTEs or cross joining system tables on each other. Once you've got the list of numbers, you can generate a list of dates, and do the maths on that. – Bridge Nov 02 '15 at 08:46

3 Answers3

1

You have to select dates greater than say 'From' date and lesser than 'To' date. I have posted the following without testing so please test and let me know in case of any errors.

SELECT Price FROM Pricing WHERE start_date >= '2015-05-30' AND end_date <= '2015-06-02'

Edit: Please make sure the start_date and end_date have the same type as the dates provided. Just to be on the safe side, you could also convert them into datetime or convert(varchar, yourDatevariable, 103) but you have to apply it on both sides of the condition.

Sorrel Vesper
  • 414
  • 4
  • 18
1

What you need to do is have a range of dates (ie, 1 row per date). This can be done a few ways. Probably the most efficient is having a calendar table, but if you cannot add new tables that is not possible.

You can have a table of numbers and add that to the starting date of each row, but again this requires a new table.

As such the option is to have a set of unioned queries to generate a range of numbers. For example the following will return 10 rows with the numbers 0 to 9:-

SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9

You can cross join such sub queries against each other to generate a larger range of numbers, and add that to your start date where the results is less than of equal to the end date:-

SELECT id, start_date, end_date, price_per_day, DATE_ADD(start_date, INTERVAL (units.a + tens.a * 10 + hundreds.a * 100) DAY) AS aDay
FROM pricing
CROSS JOIN (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
CROSS JOIN (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
CROSS JOIN (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) hundreds
WHERE DATE_ADD(start_date, INTERVAL (units.a + tens.a * 10 + hundreds.a * 100) DAY) <= end_date

The above will cope with up to 1000 days between the dates. Easy to expand to cope with 10000 days or more, but will become slower.

You can then just use that as a sub query when checking the date range you are interested in:-

SELECT aDay, price_per_day
FROM
(
    SELECT id, start_date, end_date, price_per_day, DATE_ADD(start_date, INTERVAL (units.a + tens.a * 10 + hundreds.a * 100) DAY) AS aDay
    FROM pricing
    CROSS JOIN (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
    CROSS JOIN (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
    CROSS JOIN (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) hundreds
    WHERE DATE_ADD(start_date, INTERVAL (units.a + tens.a * 10 + hundreds.a * 100) DAY) <= end_date
) sub0
WHERE aDay BETWEEN '2015-05-30' AND '2015-06-02'
ORDER BY aDay
Kickstart
  • 21,403
  • 2
  • 21
  • 33
0

Your request should look something like this :

SELECT Price FROM Pricing WHERE start_date = 2015-05-30 AND end_date = 2015-06-02

But to print out everydate date between those two, i've no idea.

This might help you thought :

How to list all dates between two dates

Community
  • 1
  • 1
Nirnae
  • 1,315
  • 11
  • 23