объединение записей для таблицы sql на основе данных столбца - PullRequest
1 голос
/ 27 марта 2012

У меня есть некоторые грязные записи об использовании ресурсов в t_resourcetable, который выглядит так

resNo   subres    startdate                        enddate
1        2        2012-01-02 22:03:00.000          2012-01-03 00:00:00.000
1        2        2012-01-03 00:00:00.000          2012-01-04 00:00:00.000
1        2        2012-01-04 00:00:00.000          2012-01-04 16:23:00.000
1        3        2012-01-06 16:23:00.000          2012-01-06 22:23:00.000
2        2        2012-01-04 05:23:00.000          2012-01-06 16:23:00.000

мне нужно, чтобы эти грязные строки были объединены таким образом

resNo   subres    startdate                        enddate
1        2        2012-01-02 22:03:00.000          2012-01-04 16:23:00.000
1        3        2012-01-06 16:23:00.000          2012-01-06 22:23:00.000
2        2        2012-01-04 05:23:00.000          2012-01-06 16:23:00.000

это должно быть обновлено до той же таблицы, у меня более 40 тыс. Строк, поэтому я не могу использовать курсор, пожалуйста, помогите мне очистить этот вид данных с помощью некоторых оптимизированных SQL-операторов.

решение поставляется с temptable и group не встречает сценарий, как. я ищу без курсора на основе решения этой проблемы

resNo   subres    startdate                        enddate
1        2        2012-01-02 22:03:00.000          2012-01-03 00:00:00.000
1        2        2012-01-03 00:00:00.000          2012-01-04 00:00:00.000
1        2        2012-01-04 00:00:00.000          2012-01-04 16:23:00.000
1        2        2012-01-14 10:09:00.000          2012-01-15 00:00:00.000
1        2        2012-01-15 00:00:00.000          2012-01-16 00:00:00.000
1        2        2012-01-16 00:00:00.000          2012-01-16 03:00:00.000
1        3        2012-01-06 16:23:00.000          2012-01-06 22:23:00.000
2        2        2012-01-04 05:23:00.000          2012-01-06 16:23:00.000

Мне нужно, чтобы эти грязные строки были объединены таким образом

resNo   subres    startdate                        enddate
1        2        2012-01-02 22:03:00.000          2012-01-04 16:23:00.000
1        2        2012-01-14 10:09:00.000          2012-01-16 03:00:00.000
1        3        2012-01-06 16:23:00.000          2012-01-06 22:23:00.000
2        2        2012-01-04 05:23:00.000          2012-01-06 16:23:00.000

Плезай, вытащи меня из этой грязной проблемы с данными

Ответы [ 3 ]

1 голос
/ 27 марта 2012

вам нужно сгруппировать данные по resNo и subRes следующим образом:

select resNo, subRes, min(startdate), max(enddate)
from  t_resourcetable
group by resNo, subRes

и вставить результат во временную таблицу.

Затем вы можете обрезать t_resourcetable и вставить результат извременная температура

0 голосов
/ 27 марта 2012

Вы можете попробовать это?

SELECT resno,
       subres,
       startdate,
       MIN(enddate) AS enddate
FROM   (SELECT t1.resno,
               t1.subres,
               t1.startdate,
               t2.enddate
        FROM   t_resourcetable t1,
               t_resourcetable t2
        WHERE  t1.enddate <= t2.enddate
               AND NOT EXISTS (SELECT *
                               FROM   t_resourcetable t3
                               WHERE  ( t1.resno = t3.resno
                                        AND t1.subres = t3.subres
                                        AND t1.startdate > t3.startdate
                                        AND t1.startdate <= t3.enddate )
                                       OR ( t2.resno = t3.resno
                                            AND t2.subres = t3.subres
                                            AND t2.enddate >= t3.startdate
                                            AND t2.enddate < t3.enddate )))t
GROUP  BY resno,
          subres,
          startdate 

Изображение похоже на

TimeLine

0 голосов
/ 27 марта 2012

Первый шаг - создать резервную копию:

select * 
into t_resourcetable_backup20120327
from t_resourcetable

Затем обновите конечную дату для первых записей, сгруппированных по resNo и subRes:

update t_resourcetable
set enddate = (select max (enddate) 
                 from t_resourcetable t1 
                where t1.resNo = t_resourcetable.resNo
                  and t1.subRes = t_resourcetable.subRes)
 where not exists (select null
                 from t_resourcetable t1
                where t1.resNo = t_resourcetable.resNo
                  and t1.subRes = t_resourcetable.subRes
                  and t1.startdate < t_resourcetable.startdate)

И, наконец, удалить лишние записи:

delete t_resourcetable
 where exists (select null
                 from t_resourcetable t1
                where t1.resNo = t_resourcetable.resNo
                  and t1.subRes = t_resourcetable.subRes
                  and t1.startdate < t_resourcetable.startdate)

Это оставит дубликаты, если у вас есть дубликаты начальных дат для уникальной комбинации resNo и subRes. Вы также должны проверить, всегда ли у конечных дат есть соответствующие начальные даты, потому что вы потеряете пробелы - но это может быть просто то, что вам нужно.

Помимо создания резервной копии, вы можете обернуть обновление / удаление в транзакции, сделать выбор после удаления и откат, затем проверить данные в Excel и, если все выглядит нормально, повторить транзакцию, но зафиксировать ее на этот раз.

ОБНОВЛЕНИЕ: этот запрос выявляет пробелы. Если вы используете Sql Server 2000, преобразуйте CTE в производные таблицы. Сначала возвращает список ресурсов, не имеющих предшественников, последний делает то же самое для наследников. Оба считают пробелы. Затем списки объединяются с помощью resNo, subRes и номера пробела.

;with first as (
    select resNo, subres, startdate,
  row_number() over (partition by resNo, subres order by startdate) rowNumber
      from t_resourcetable
     where not exists (select null
                       from t_resourcetable t1
                      where t1.resNo = t_resourcetable.resNo
                        and t1.subres = t_resourcetable.subres
                        and t1.enddate = t_resourcetable.startdate)
),
last as (
  select resNo, subres, enddate,
  row_number () over (partition by resNo, subres order by enddate) rowNumber
  from t_resourcetable
     where not exists (select null
                       from t_resourcetable t1
                      where t1.resNo = t_resourcetable.resNo
                        and t1.subres = t_resourcetable.subres
                        and t1.startdate = t_resourcetable.enddate)
)
select first.resno, first.subres, first.startdate, last.enddate
from first 
  inner join last
  on first.resNo = last.resNo
    and first.subres = last.subres
    and first.rowNumber = last.rowNumber
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...