Добавление одного месяца к дате, если два значения попадают в один и тот же месяц, а затем повторение проверки достоверности (рекурсия?) - PullRequest
1 голос
/ 01 октября 2010

У меня есть довольно сомнительные данные, на которые я смотрю, и мне было поручено выяснить, сколько месяцев подряд что-то происходит.Однако я заметил, что в некоторых из моих справочных таблиц отдельные значения даты неправильно закодированы, и если в одном месяце есть несколько значений, самое последнее следует добавить в следующий месяц.

Например:

Contact _id  | Original Payment Date 
id001        |  02/07/2003
id001        |      30/07/2003 --should be changed to 30/08/2003
id001        |      01/09/2003
id001        |      01/10/2003 
id001        |      30/10/2003 -- should be changed to 30/11/2003
id001        |      02/12/2003
id001        |      31/12/2003 -- should be changed to 31/01/2004
id001        |      30/01/2004
id001        |      03/03/2004

Однако при простой функции DATEADD я нахожу две проблемы:

1) Если платеж необходимо перенести в следующий месяц, и его дата больше, чем в следующем, позволяет(то есть 31.01.2003 не может перейти к 31.02.2003) Я не уверен, как dateadd будет работать в этом случае

2) Если в приведенном выше примере я внесу эти изменения, у нас естьследующие данные:

id001        |      02/07/2003
id001        |      30/08/2003
id001        |      01/09/2003
id001        |      01/10/2003
id001        |      30/11/2003
id001        |      02/12/2003
id001        |      31/01/2004 --This should now be changed to a value in Februrary 2004 as there are
 now duplicates in January 2004 created by the previous amendment
 id001       |     30/01/2004
id001        |      03/03/2004

Хотя я полагаю, что 2 «цикла» изменений позволят убедиться, что все данные верны, я не уверен, и поэтому мне очень хотелось бы, чтобы какой-то способ подтолкнуть последнюю дату вмесяц (где для этого месяца 2 значения) переслать месяц, который повторяется до тех пор, пока по возможности больше не будет дубликатов.

Я использую sql server 2005 и справочную таблицу hоколо 20 миллионов строк, поэтому я бы предпочел не использовать курсоры, если это возможно:)

Спасибо!

update Скрипт, который я использую для обновления датпервый раз это:

;WITH cte1 AS (  
SELECT  contact_id
        ,value_net
        ,DATEPART(YEAR, date_received)*12 + DATEPART(MONTH, date_received) -  
        DENSE_RANK() OVER  
                   (PARTITION BY contact_id  
                    ORDER BY DATEPART(YEAR, date_received)*12 + DATEPART(MONTH, date_received)) AS dategroup
        ,DENSE_RANK() OVER  
                   (PARTITION BY contact_id  
                    ORDER BY DATEPART(YEAR, date_received)*12 + DATEPART(MONTH, date_received)) AS rnk
        ,ROW_NUMBER() OVER  
                   (PARTITION BY contact_id  
                    ORDER BY DATEPART(YEAR, date_received)*12 + DATEPART(MONTH, date_received)) AS rnk2

        ,date_received 
FROM    donation with (nolock)
WHERE contact_id IS NOT NULL
 )
,cte2 AS
(
SELECT 
c1.contact_id
,c1.value_net
,c1.dategroup
,CASE WHEN c1.rnk = c2.rnk AND c1.rnk2 > c2.rnk2 THEN DATEADD(MM,+1,c1.date_received) ELSE c1.date_received END as date_received
from cte1 c1
LEFT OUTER JOIN cte1 c2 WITH (nolock) ON c2.contact_id = c1.contact_id AND c2.rnk = c1.rnk AND c2.rnk2 = c1.rnk2-1
)

1 Ответ

1 голос
/ 01 октября 2010

1) DATEADD () с МЕСЯЦЕМ от 1 до 2010-01-31 приведет к 2010-02-28

2) Проблема будет в дублировании и идентификацииконкретная строка в пределах дубликатов.Например, вы хотите сместить все, кроме первого, но что, если сначала будет несколько, они не будут смещены - то есть вы делаете что-то вроде этого:

UPDATE dates
SET dt = DATEADD(MONTH, 1, dt)
WHERE YEAR(dt) * 100 + MONTH(dt) IN (
    SELECT YEAR(dt) * 100 + MONTH(dt)
    FROM dates
    GROUP BY YEAR(dt), MONTH(dt)
    HAVING COUNT(*) > 1
)
AND dt NOT IN (
    SELECT MIN(dt)
    FROM dates
    GROUP BY YEAR(dt), MONTH(dt)
    HAVING COUNT(*) > 1
)

Вы, вероятно, можете изменить это наиспользуйте ROW_NUMBER () OVER () для уникальной идентификации строк.

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