Reputation: 321
I have a table (SQL Server 2017) containing data within a date range.
+---------+----------+------------+---------------+-------------+
| good_id | store_id | promo_name | date_id_begin | date_id_end |
+---------+----------+------------+---------------+-------------+
| 1122 | 42 | promo_1 | 2020-02-01 | 2020-02-05 |
+---------+----------+------------+---------------+-------------+
| 2244 | 41 | promo_2 | 2020-03-01 | 2020-03-03 |
+---------+----------+------------+---------------+-------------+
I need to get this data by day within the period.
+---------+----------+------------+---------------+
| good_id | store_id | promo_name | date_id_begin |
+---------+----------+------------+---------------+
| 1122 | 42 | promo_1 | 2020-02-01 |
+---------+----------+------------+---------------+
| 1122 | 42 | promo_1 | 2020-02-02 |
+---------+----------+------------+---------------+
| 1122 | 42 | promo_1 | 2020-02-03 |
+---------+----------+------------+---------------+
| 1122 | 42 | promo_1 | 2020-02-04 |
+---------+----------+------------+---------------+
| 1122 | 42 | promo_1 | 2020-02-05 |
+---------+----------+------------+---------------+
| 2244 | 41 | promo_2 | 2020-03-01 |
+---------+----------+------------+---------------+
| 2244 | 41 | promo_2 | 2020-03-02 |
+---------+----------+------------+---------------+
| 2244 | 41 | promo_2 | 2020-03-03 |
+---------+----------+------------+---------------+
I can extract dates from a range inside the loop, but how can I select other information (good_id, store_id, promo_name)?
Upvotes: 1
Views: 40
Reputation: 81930
If you don't have a calendar or tally table, you can use an ad-hoc tally table.
Example
Select A.[good_id]
,A.[store_id]
,A.[promo_name]
,[Date] = B.D
From YourTable A
Join (
Select Top (25000) D=DateAdd(DAY,Row_Number() Over (Order By (Select Null)),'1999-12-31') From master..spt_values n1,master..spt_values n2
) B on D between date_id_begin and date_id_end
Returns
good_id store_id promo_name Date
1122 42 promo_1 2020-02-01
1122 42 promo_1 2020-02-02
1122 42 promo_1 2020-02-03
1122 42 promo_1 2020-02-04
1122 42 promo_1 2020-02-05
2244 41 promo_2 2020-03-01
2244 41 promo_2 2020-03-02
2244 41 promo_2 2020-03-03
Upvotes: 1
Reputation: 222402
One option is a recursive query:
with cte as (
select good_id, store_id, promo_name, date_id_begin, date_id_end
from mytable
union all
select good_id, store_id, promo_name, dateadd(day, 1, date_id_begin), date_id_end
from cte
where date_id_begin < date_id_end
)
select good_id, store_id, promo_name, date_id_begin from cte
If you have ranges that spread over more than 100 days, you need to add option(max_recursion 0)
at the end of the query.
Upvotes: 1