2016-11-02 2 views
2

Очень жаль, если на это был дан ответ в некотором роде. Я все проверил и не могу понять.Сравнение двух наборов данных

Мне нужно найти способ в postgresql для сравнения данных из недели в неделю. Все данные существуют в одной таблице и имеют столбец Число недели. Данные не всегда полностью перекрываются, но мне нужно сравнивать данные внутри групп, когда они это делают.

Скажем, эти наборы данных:

Week 2 
+--------+--------+------+---------+-------+ 
| group | num | color| ID  | week #| 
+--------+--------+------+---------+-------+ 
| a | 1 | red | a1red | 2 | 
| a | 2 | blue | a2blue | 2 | 
| b | 3 | blue | b3blue | 2 | 
| c | 7 | black| c7black | 2 | 
| d | 8 | black| d8black | 2 | 
| d | 9 | red | d9red | 2 | 
| d | 10 | gray | d10gray | 2 | 
+--------+--------+------+---------+-------+ 

Week 3 
+--------+--------+------+---------+-------+ 
| group | num | color| ID  | week #| 
+--------+--------+------+---------+-------+ 
| a | 1 | red | a1red | 3 | 
| a | 2 | green| a2green | 3 | 
| b | 3 | blue | b3blue | 3 | 
| b | 5 | green| b5green | 3 | 
| c | 7 | black| c7black | 3 | 
| e | 11 | blue | d11blue | 3 | 
| e | 12 | other| d12other| 3 | 
| e | 14 | brown| d14brown| 3 | 
+--------+--------+------+---------+-------+ 

Каждая строка имеет идентификатор, сделанный из группы значений, количество и цвет.

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

  1. флаг идентификаторы в пределах группы, которые изменились, как и в группе А.
  2. флаг, если были добавлены или удалены любые идентификаторы в группе, как и в группе В.

Одна из функций, которые было бы неплохо иметь, но не является обязательным, будет иметь Неделя 3 сравниваться неделя 1 для групп, которых нет в Неделе 2.

Я думал о попытке разделить две недели и использовать перехват/за исключением получения результатов, но я не могу полностью окутать голову, как я могу заставить это работать правильно. Любые советы будут высоко оценены.

+1

Где номер недели, скрытые в этой таблице? –

+0

Его просто еще одна колонка. Обновлена ​​таблица, чтобы прояснить это. – Jakewb89

ответ

0

Для всего два (известных) недель вы можете сделать что-то вроде этого:

select coalesce(w1.group_nr, w2.group_nr) as group_nr, 
     coalesce(w1.num, w2.num) as num, 
     case 
     when w1.group_nr is null then 'missing in first week' 
     when w2.group_nr is null then 'missing in second week' 
     when (w1.color, w1.id) is distinct from (w2.color, w2.id) then 'data has changed' 
     else 'no change' 
     end as status, 
     case 
      when 
       w1.group_nr is not null 
      and w2.group_nr is not null 
      and w1.color is distinct from w2.color then 'color is different' 
     end as color_change, 
     case 
      when 
       w1.group_nr is not null 
      and w2.group_nr is not null 
      and w1.id is distinct from w2.id then 'id is different' 
     end as id_change 
from (
    select group_nr, num, color, id, hstore 
    from data 
    where week = 2 
) as w1 
    full outer join (
    select group_nr, num, color, id 
    from data 
    where week = 3 
) w2 on (w1.group_nr, w1.num) = (w2.group_nr, w2.num) 

Получение атрибутов, которые изменились немного неуклюжим. Если вы можете жить с текстовым представлением, вы могли бы использовать расширение hstore для отображения различий:

select coalesce(w1.group_nr, w2.group_nr) as group_nr, 
     coalesce(w1.num, w2.num) as num, 
     case 
     when w1.group_nr is null then 'missing in first week' 
     when w2.group_nr is null then 'missing in second week' 
     when (w1.color, w1.id) is distinct from (w2.color, w2.id) then 'data has changed' 
     else 'no change' 
     end as status, 
     w2.attributes - w1.attributes as changed_attributes 
from (
    select group_nr, num, color, id, hstore(data) - 'week'::text as attributes 
    from data 
    where week = 2 
) as w1 
    full outer join (
    select group_nr, num, color, id, hstore(data) - 'week'::text as attributes 
    from data 
    where week = 3 
) w2 on (w1.group_nr, w1.num) = (w2.group_nr, w2.num); 
+0

Ах! Большое спасибо. После того, как вы выложили основной процесс мышления, все щелкнуло на месте и теперь работает отлично. – Jakewb89

Смежные вопросы