Не удалось получить currval или lastval последовательности в запросе в greenplum, использующем postgresql 8.3.

Я пытаюсь решить проблему в запросе без написания функции. У меня есть таблица с информацией о пользователе, как показано ниже:

user_id user_name user_phone_number user_location created_at
1         abc          123              X         2014-01-01
1         abc          123              X         2014-02-01
1         abc          123              Y         2014-10-01
1         abc          123              Z         2014-11-01
1         abc          123              Z         2014-12-01
1         abc          123              X         2015-01-01

Мне нужно сделать это в таблице SCD-Type II, как показано ниже:

user_id user_name user_ph_num user_location valid_from_dt valid_to_dt   
1         abc        123         X           2014-01-01   2014-09-30
1         abc        123         Y           2014-10-01   2014-10-31
1         abc        123         Z           2014-11-01   2014-12-31
1         abc        123         X           2015-01-01   2999-12-31

что я думал, чтобы это произошло:

За один шаг: temp_table1:

id user_name user_ph_num user_location created_at is_same_with_previous
1         abc     123              X   2014-01-01          f
1         abc     123              X   2014-02-01          t
1         abc     123              Y   2014-10-01          f
1         abc     123              Z   2014-11-01          f
1         abc     123              Z   2014-12-01          t
1         abc     123              X   2015-01-01          f

На втором этапе:

temp_table2:

id user_name user_ph_num user_loc created_at is_same_with_previous sr_no
1         abc     123        X    2014-01-01          f             1
1         abc     123        X    2014-02-01          t             1
1         abc     123        Y    2014-10-01          f             2
1         abc     123        Z    2014-11-01          f             3
1         abc     123        Z    2014-12-01          t             3
1         abc     123        X    2015-01-01          f             4

После этого я могу запросить, как показано ниже, и получить желаемый результат:

select id,user_name,user_ph_num,user_loc,min(created_at) as valid_from,
max(created_at) as valid_to
from temp_table2
group by sr_no,id,user_name,user_ph_num,user_loc;

Я создал шаг-1 и не могу создать temp_table2 (шаг-2). Для этого я использую следующий запрос:

select setval('ser_no',2);

select *
CASE WHEN is_same_with_previous 
THEN (SELECT setval('ser_no',nextval('ser_no')-1))
ELSE nextval('ser_no') END as diff_sr_no
from temp_table1;

В результате получается: temp_table2:

id user_name user_ph_num user_loc created_at is_same_with_previous sr_no
1         abc     123        X    2014-01-01          f             1
1         abc     123        X    2014-02-01          t             1
1         abc     123        Y    2014-10-01          f             2
1         abc     123        Z    2014-11-01          f             3
1         abc     123        Z    2014-12-01          t             1
1         abc     123        X    2015-01-01          f             4

Может ли кто-нибудь помочь решить эту проблему? Я использую правильный подход? Заранее спасибо!!!


person preetham nadella    schedule 20.04.2015    source источник


Ответы (1)


Вы используете неправильный подход. Вам следует взглянуть на «оконные функции» в базах данных, вам могут понадобиться «row_number()», «rank()» и «lag()». Обычно создание SCD2 можно выполнить одним запросом. В вашем случае запрос должен:

  1. Удалить дубликаты во всех полях
  2. Применить rank() к разделу по всем полям, кроме «created_at» и порядка «created_at»
  3. Для каждого ранга выберите минимум "created_at"
  4. «created_at» — это valid_from, «отставание (created_at) от раздела на (порядок created_at desc)» как valid_to
person 0x0FFF    schedule 06.08.2015