2013-10-04 2 views
0
date,    product, new_col, 
2013/05/16,   A, 
2013/05/18,   A, 
2013/06/15,   A, 
2013/05/16,   B, 
2013/06/13,   B, 
2013/06/20,   B 

Я использую SQL Server 2008.5 новых записей для каждой существующей строки

Для каждой существующей записи, в new_col мне нужно хранить в new_col 5 предыдущий календарные даты, вплоть до даты, указанной в date колонка. Например. для первого ряда в приведенной выше таблице мне нужно 5/16,5/15,5/14,5/13,5/12 в new_col.

У меня есть много продуктов в таблице и множество дат для каждого продукта.

Я попытался разбить таблицу на основе этих двух столбцов, но не могу определить способ ввода 5 дней в new_col.

Пожалуйста, помогите с любыми предложениями для этого.

+0

ли это сделать в SQL? Это может быть намного проще на уровне приложений или отчетов. –

+3

Наличие столбца с несколькими значениями, разделенными запятой, не является хорошей идеей. –

+0

Какое SQL-серверное программное обеспечение вы используете? –

ответ

0

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

CREATE TABLE dbo.Sam ([Date] DATE, Product VARCHAR(10), NewCol VARCHAR(1000)) 
INSERT INTO dbo.Sam 
SELECT '2013/05/16','A',NULL 
UNION ALL SELECT '2013/05/18','A',NULL 
UNION ALL SELECT '2013/06/15','A',NULL 
UNION ALL SELECT '2013/05/16','B',NULL 
UNION ALL SELECT '2013/06/13','B',NULL 
UNION ALL SELECT '2013/06/20','B',NULL 

GO 


CREATE FUNCTION dbo.fnGet4PreviousDates(@Date DATE, @Product VARCHAR(10)) 
    RETURNS VARCHAR(1000) 
AS 
BEGIN 

    DECLARE @Out VARCHAR(1000) = '' 


    SELECT @Out = @Out + CONVERT(VARCHAR,[Date],112) + ',' 
    FROM (
     SELECT TOP 5 [Date] 
     FROM dbo.Sam 
     WHERE Product = @Product 
     AND [Date] < @Date 
     ORDER BY [Date] DESC 
    ) t 

    RETURN @Out 

END 
GO 

UPDATE dbo.Sam 
SET NewCol = dbo.fnGet4PreviousDates([Date],Product) 

SELECT * FROM dbo.Sam 
1
WITH cal AS (
    SELECT CAST('20130101' AS DATE) as cal_date 
    UNION ALL 
    SELECT DATEADD(day, 1, cal_date) 
    FROm cal 
    WHERE cal_date < CAST('20131231' AS DATE) 
) 
SELECT 
    [date],[product], 
    new_col = STUFF((SELECT ',' + CONVERT(VARCHAR(10),cal.cal_date,111) 
       FROM cal 
       WHERE cal.cal_date BETWEEN DATEADD(day, -4, tbl.[date]) AND tbl.[date] 
       ORDER BY cal.cal_date DESC  
       FOR XML PATH('')  
      ),1,1,'') 
FROM tbl 
OPTION (maxrecursion 0) 

sql fiddle demo

Смежные вопросы