Вы можете сделать это, как этот
SELECT pno, startdate + INTERVAL q.n - 1 DAY dates
FROM table1 t CROSS JOIN
(
SELECT a.N + b.N * 10 + 1 n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
ORDER BY n
) q
WHERE q.n - 1 <= DATEDIFF(enddate, startdate)
ORDER BY pno, dates
Подзапрос генерирует последовательность чисел от 1 до 100. Вы можете настроить его для ваших нужд (если охватывают даты различия более или менее чем за 100 дней) или полностью заменить его таблицей с сохраненными таблицами (числами), если вы выполняете много таких запросов.
Выход:
+------+------------+
| pno | dates |
+------+------------+
| p1 | 2012-12-03 |
| p1 | 2012-12-04 |
| p1 | 2012-12-05 |
| p1 | 2012-12-06 |
| p2 | 2013-01-05 |
| p2 | 2013-01-06 |
| p2 | 2013-01-07 |
| p2 | 2013-01-08 |
| p3 | 2013-01-15 |
| p3 | 2013-01-16 |
| p3 | 2013-01-17 |
| p3 | 2013-01-18 |
| p3 | 2013-01-19 |
| p3 | 2013-01-20 |
+------+------------+
Вот SQLFiddle демо
UPDATE: Для создания и заполнения PERSISTED Tally таблица использования
CREATE TABLE tally (n INT NOT NULL PRIMARY KEY);
INSERT INTO tally (n)
SELECT a.n + b.n * 10 + c.n * 100 + d.n * 1000 + 1 n
FROM
(SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
,(SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
,(SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) d
ORDER BY n;
Y ou'll будет в последовательности таблиц таблицы от 1 до 10000. Это позволит вам работать с диапазонами дат, которые охватывают более 27 лет.
Теперь запрос сводится к
SELECT pno, startdate + INTERVAL q.n - 1 DAY dates
FROM table1 t CROSS JOIN tally q
WHERE q.n - 1 <= DATEDIFF(enddate, startdate)
ORDER BY pno, dates
Вот SQLFiddle демо
для дат с пролетом более 2-х лет – user2825758
@ user2825758 См обновленный ответ и sqlfiddle пример. Создайте таблицу постоянных таблиц (чисел) с предоставленным скриптом и используйте их. ИМХО это самый быстрый и общий способ ** работать с диапазонами дат. Любой другой подход потребует использовать хранимую процедуру для использования циклов и будет медленнее и менее гибким. – peterm
@ user2825758 Если вы чувствуете, что ответ был полезным, рассмотрите ** [accept] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) ** it , – peterm