MSSQL - создание записей для записей, которые не существуют за последние 7 дней - PullRequest
1 голос
/ 13 февраля 2012

У меня есть веб-сайт ASP.NET с бэкэндом C #, использующим MSSQL SQL Server 2008 для его содержимого.

Я написал следующую хранимую процедуру, которая проверяет все записи в течение последних 7 дней, а затемвозвращает то, что находит.

ALTER PROCEDURE [dbuser].[GetResponses] 
    (
    @QUEST_ID int
    )   
AS
    SELECT DateAdded, SUM(Responses) AS responseCount
    FROM ActiveResponses
    WHERE @QUEST_ID = QuestionnaireID AND DateAdded >= dateadd(day,datediff(day,0,GetDate())- 6,0)
    GROUP BY DateAdded
    RETURN

Моя проблема здесь в том, что если в течение какого-либо из этих последних 7 дней не существует записей, то мой метод на задней стороне веб-сайта завершится ошибкой, так как для этого потребовалось 7 записей.Например:

Допустим, у меня есть следующие записи в моей таблице

-DateAdded--------Responses
2012-02-12           4
2012-02-11           5
2012-02-10           8
2012-02-08           7
2012-02-07           3

Обратите внимание, что нет записей для обоих 2012-02-13 (сегодня)и 2012-02-09

Как создать оператор SQL, который проверяет количество ответов за последние 7 дней, и если для любого из них найдены записи no в один из дней он создает запись с ответом 0 в правильной позиции?

Ответы [ 3 ]

2 голосов
/ 13 февраля 2012

Это хорошее применение таблицы чисел (например: http://www.projectdmx.com/tsql/tblnumbers.aspx)

Предполагая, что у вас есть таблица чисел dbo.Nums, в которой есть как минимум 6 чисел, вы можете попробовать следующее:

CREATE TABLE #Dates
(
    [Date] DATETIME
)

INSERT INTO #Dates
(
    [Date]
)
SELECT
    DATEADD(DD, DATEDIFF(DD, 0, GETDATE()) - ([n] - 1), 0)
FROM
    [dbo].[Nums] WITH (NOLOCK)
WHERE
    [n] < 7

SELECT
    [Date],
    ISNULL(SUM([Responses]), 0) AS [responseCount]
FROM
    #Dates AS d
LEFT OUTER JOIN
    ActiveResponses AS a
ON
    a.[DateAdded] = d.[Date]
WHERE
    @QUEST_ID = QuestionnaireID
ORDER BY
    [Date] ASC
0 голосов
/ 14 февраля 2012

Объявите переменную таблицы с последними семью датами и включите ее в свой запрос:

ALTER PROCEDURE [dbuser].[GetResponses] 
    (
    @QUEST_ID int
    )   
AS
DECLARE @i INT=0;
DECLARE @today DATE=getdate();
DECLARE @last7 TABLE(DateAdded DATE);

WHILE @i>-7 BEGIN
    INSERT INTO @last7 VALUES (DATEADD(DAY,@i,@today));
    SET @i -= 1;
END

;WITH a AS (
    SELECT ar.DateAdded, count(ar.Responses) as responseCount
    FROM ActiveResponses ar
    INNER JOIN @last7 z ON z.DateAdded=ar.DateAdded
    WHERE @QUEST_ID = ar.QuestionnaireID
    GROUP BY ar.DateAdded
)
SELECT DateAdded=ISNULL(a.DateAdded,z.DateAdded)
, responseCount=ISNULL(a.responseCount,0)
FROM @last7 z
LEFT JOIN a ON a.DateAdded=z.DateAdded;
RETURN;
GO

Результаты:

DateAdded  responseCount
---------- -------------
2012-02-13 0
2012-02-12 4
2012-02-11 5
2012-02-10 8
2012-02-09 0
2012-02-08 7
2012-02-07 3
0 голосов
/ 13 февраля 2012

Это демонстрирует получение сводных данных за каждый день недели, даже если некоторые дни не имеют данных:

declare @Data as table ( DateAdded date, Responses int )
insert into @Data ( DateAdded, Responses ) values ( '2/10/2012', 5 ), ( '2/13/2012', 9 )

; with James as (
  select cast( SysDateTime() as date ) as StartOfDay, 7 as DaysLeft
  union all
  select DateAdd( d, -1, StartOfDay ), DaysLeft - 1
    from James
    where DaysLeft > 1
  )
  select J.StartOfDay, DateAdd( ms, -3, cast( DateAdd( day, 1, J.StartOfDay ) as DateTime ) ) as EndOfDay, Coalesce( D.Responses, 0 ) as Responses
    from James as J left outer join
      @Data as D on D.DateAdded = J.StartOfDay
    order by J.StartOfDay desc

Оставленное в качестве упражнения сопрягает это с данными вашей анкеты.

Обратите внимание, что самое близкое к полуночи время, представленное значениями DateTime, составляет 3 мс до полуночи.Вы можете использовать значения StartOfDay и EndOfDay, чтобы сбрасывать любые DateAdded в правильные даты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...