Объединить записи в SQL с последующими датами? - PullRequest
0 голосов
/ 21 февраля 2011

Я хочу объединить следующие данные, используя sql:

no code area rate startdate enddate  
1  0101 EU   0.1% 20050101  20051231  
2  0101 EU   0.1% 20060101  20061231
3  0101 EU   0.1% 20080101  20081231  
4  0101 EFTA 0.2% 20050101  20051231  
5  0101 EFTA 0.1% 20060101  20061231  
  • В приведенном выше примере № 1 и 2 должны быть объединены, так как они имеют одинаковый код, одинаковую скорость, имеют последующие даты ииз той же области.
  • № 3 не должны объединяться, поскольку даты не являются последующими.
  • 4 и 5 не должны объединяться, поскольку они имеют разные ставки.

Конечный результат должен выглядеть следующим образом:

no code area rate startdate enddate  
1  0101 EU   0.1% 20050101  20061231  
3  0101 EU   0.1% 20080101  20081231  
4  0101 EFTA 0.2% 20050101  20051231  
5  0101 EFTA 0.1% 20060101  20061231  

Есть ли способ сделать это, используя только sql?Я использую postgres.

Спасибо

Ответы [ 3 ]

1 голос
/ 21 февраля 2011

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

Я не знаю Postgres, но, похоже, у них есть курсоры, которые работают аналогично MS-Sql: http://www.postgresql.org/docs/current/static/plpgsql-cursors.html

Курсоры позволяют вам «проходить» через оператор выбора, помещая значения ввременные переменные, где вы можете работать с ними.Это больше похоже на процедурное программирование.

Производительность невелика, поэтому все нормально, но она может быть более сложной (но более производительной), если у вас есть проблемы с производительностью.

Я бы начал с создания курсора для циклического перемещения по таблице, помещения кода, скорости, начальной даты и конца в переменные.(Если вы сортируете оператор выбора по коду, ставке и начальной дате, вы гарантируете, что все ваши записи будут отображаться в правильном для вас порядке.) Для каждой записи вы можете сравнить текущий код и оценку со значением в переменной, иесли они одинаковые, обновите переменную конечной даты.

Используйте 2-ую таблицу (или переменную таблицы) для результатов.Если код / ​​скорость не совпадают с переменными, то все в переменных является кандидатом новой строки.Запишите его, затем обновите переменные новыми данными и продолжайте.

За один раз вы создадите новую таблицу.Затем вы можете удалить исходный файл и заменить его или сохранить в другом месте.

0 голосов
/ 05 мая 2014

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

  1. Создать дополнительную таблицу с новым столбцом Последующий (int). Скопируйте все строки из исходной таблицы в этот новый заполняющий новый столбец «Последующий» следующим образом: если начальная дата строки равна конечной дате предыдущей строки, то «Последующая» = 1 (означает, что эта строка следует за предыдущей), если не равно 0 (означает, что в этой строке начинается новая последовательность). Чтобы найти дату окончания предыдущей строки, используйте функцию lag (), разделенную по коду и области и упорядоченную по дате начала. Например, в приведенном выше примере строки №. 2 будет иметь последующее = 1, а все остальные последующие = 0.

  2. Напишите запрос, который выберет из приведенной выше таблицы только строки, в которых «Последующий» = 0, т.е. «исходные», с кодом и скоростью, а затем найдет максимальную дату окончания среди всех последующих строк, следующих за исходной строкой для каждой выбранной исходной строки.

Максимальная дата окончания может быть найдена с помощью такого подзапроса:

(A) Попробуйте найти его среди последующих строк, следующих за этой оригинальной:

выбрать максимальную дату окончания из всех строк, которые соответствуют критериям:

  • следующий - 1, то есть только последующие строки
  • код равен коду исходной строки
  • ставка равна коду исходной строки
  • дата начала больше даты начала исходной строки
  • конечная дата меньше начальной даты следующей исходной строки или, если следующей исходной строки нет, тогда конечная дата = максимум всех конечных дат в этой комбинации кода и скорости "

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

  • последующий = 0
  • дата начала> дата начала исходной строки
  • код и скорость такие же, как в исходной строке.

(B) Если выше возвращено значение NULL, то есть исходная строка не имеет последующих строк, тогда конечной датой для этой строки является ее собственная конечная дата.

Функция объединения объединяет выбор между (A) и (B).

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

0 голосов
/ 21 февраля 2011

Может быть, я что-то упускаю, но мне кажется, что вы хотите:

SELECT DISTINCT ON (code, area, rate, startdate, enddate), 
       no, 
       code, 
       area, 
       rate, 
       startdate, 
       enddate  
FROM your_table
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...