2013-08-07 3 views
1

Использование другой статьи в StackOverflow (How to split date ranges based on months in SQL Server 2005) Я запустил оператор SELECT, который разбивает диапазон дат по месяцам и возвращает 2 столбца (DateFrom, DateTo) в SQL.SQL - преобразование результатов в строку, разделенную запятой

DECLARE @SDate DATE = '2012/08/01' 
DECLARE @EDate DATE = '2013/09/01' 

SELECT 
    DATEADD(MONTH, n.Number, @SDate) as DateFrom, 
    DATEADD(day, -1, DATEADD(MONTH, n.Number, DATEADD(YEAR,-1,@EDate))) as DateTo 
FROM 
    master.dbo.spt_values n 
WHERE 
    n.Number < DATEDIFF(MONTH, @SDate, @EDate) 
    AND n.Type = 'P' 

я теперь нужно добавить каждый из возвращаемых строк в строку, разделяющие столбцы | (Dateto|Datefrom) и каждую строку по ,.

Например, если ваш запустить код, указанный выше результат будет (только для этого примера им, используя только первые 4 строки, но мне нужно их все в одной строке):

R | Date From | Date To 
1 | 2012-08-01 | 2012-08-31 
2 | 2012-09-01 | 2012-09-30 
3 | 2012-10-01 | 2012-10-30 
4 | 2012-11-01 | 2012-11-30 

Код:

DECLARE @stralldates VarChar(MAX) 
/* SET @stralldates = INSERTCODE */ 
PRINT @stralldates 

Что мне нужно PRINT, чтобы вернуться:

2012-08-01|2012-08-31,2012-10-01|2012-10-30,2012-10-01|2012-10-30,2012-11-01|2012-11-30 

Я пытался несколько предложений от другие подобные вопросы по StackOverflow (например, CONCAT) без успеха.

Любая помощь или предложения будут оценены.

ответ

3
set @StrAllDates = 
    stuff((select ','+convert(char(10), SDate, 121)+'|'+convert(char(10), dateadd(day, -1, dateadd(month, 1, SDate)), 121) 
     from (
       select dateadd(month, n.number, @SDate) as SDate 
       from master..spt_values as n 
       where n.number < datediff(month, @SDate, @EDate) and 
        n.type = 'P' 
      ) as T 
     order by SDate 
     for xml path('')), 1, 1, '') 
+0

Спасибо за вашу помощь, это именно то, что мне нужно! –

1

Я знаю только Oracle, который предоставляет wm_concat (недокументированные) или listagg в зависимости от версии.

+0

У меня есть ответ, но спасибо за вашу помощь! –

1

Вы можете использовать приведенный ниже сценарий, чтобы получить данные в том формате, который вы хотите. В основном он использует метод coalesce для конкатенации. Я создал временную таблицу для хранения данных, которые затем используются для итерации по строкам.

DECLARE @SDate DATE = '2012/08/01' 
DECLARE @EDate DATE = '2013/09/01' 
SELECT 
    DATEADD(MONTH, n.Number, @SDate) as DateFrom, 
    DATEADD(day, -1, DATEADD(MONTH, n.Number, DATEADD(YEAR,-1,@EDate))) as DateTo 
INTO #tmp_data 
FROM master.dbo.spt_values n 
WHERE 
n.Number < DATEDIFF(MONTH, @SDate, @EDate) 
AND n.Type = 'P' 

declare @my_string varchar(8000); 
select @my_string = 
    coalesce(@my_string + ',', '') 
    + convert(varchar(10), d.DateFrom, 126) 
    + '|' + convert(varchar(10), d.DateTo, 126) 
from #tmp_data d 
order by d.DateFrom 
select @my_string 

drop table #tmp_data 

Кроме того, если вы хотите использовать строки rumber, вы можете использовать его использовать, добавив еще один столбец выбора пункта - ROW_NUMBER() OVER(ORDER BY n.Number) as RowNum

+0

Этот ответ не гарантирует, что даты будут объединены в порядке возрастания даты. Только ОП будет знать, является ли это проблемой или нет. –

+0

@Mikael Eriksson Я не понимал, что вы можете отметить только один ответ, я предполагаю, что использование искушений не будет таким же эффективным в любом случае. Но спасибо за вашу помощь сиддхарт! –

+0

Спасибо Бен. @MikaelEriksson - Мы всегда можем добавить предложение order by при выборе из таблицы temp. – siddharth

1

Следующий запрос даст вам необходимую через запятую строку:

DECLARE @Begin DATETIME 
DECLARE @End DATETIME 
Declare @test Table(startDate datetime, endDate datetime) 
DECLARE @listStr VARCHAR(MAX) 
SELECT @Begin = '20110101', @End = '20120101' 

Insert into @test 
SELECT DATEADD(MONTH, n.Number, @Begin) DateFrom, DATEADD(day, -1, DATEADD(MONTH, n.Number+1, @Begin)) DateTo 
FROM master.dbo.spt_values n 
WHERE 
    n.Number <= DATEDIFF(MONTH, @begin, @end) 
AND n.Type = 'P' 

select @listStr = COALESCE(@listStr+',' ,'')+ CONVERT(VARCHAR(10), startDate, 120) + '|' + CONVERT(varchar(10),endDate,120) from @test 
select @listStr 
Смежные вопросы