случай когда в sqldf/R

Если у меня ДФ

   A B  Col
    1 1  A
    2 2  B
    1 2  C
    2 1  D
    1 3  E
    2 3  F

Я пытаюсь использовать sqldf следующим образом

 Test <- sqldf("                SELECT A,
                                    case when A = '1' and B = '1' then Col else NULL end as Test_1, 
                                    case when A = '1' and B = '2' then Col else NULL end as Test_2, 
                                    case when A = '1' and B = '3' then Col else NULL end as Test_3, 
                                    case when A = '2' and B = '1' then Col else NULL end as Test_4, 
                                     case when A = '2' and B = '2' then Col else NULL end as Test_5, 
                                      case when A = '2' and B = '3' then Col else NULL end as Test_6 

                                   FROM  DF
                                   group by A;")

Однако он возвращает результат только для каждого случая A и других столбцов NULL, поэтому вместо желаемого

A Test1 Test2 Test3 Test4 Test5 Test6
1   A     C     E    Null  NULL  NULL
2  NULL  NULL  NULL   D      B    F

Я получаю только один результат для каждого A

A Test1 Test2 Test3 Test4 Test5 Test6
1   G    NULL  NULL  Null  NULL  NULL
2  NULL  NULL  NULL  NULL   B    NULL

Что я делаю неправильно и есть ли способ получить нужный мне формат?


person Rtab    schedule 24.08.2017    source источник
comment
Вы группируете по A, которые содержат только два значения. Попробуйте удалить GROUP BY, так как вы все равно не выполняете агрегацию.   -  person Parfait    schedule 24.08.2017
comment
Спасибо. Верно, но это все еще не решает проблему для меня   -  person Rtab    schedule 24.08.2017
comment
Ваш желаемый результат не имеет для меня смысла - если я удалю group by, я получу результат, который имеет смысл (с 8 строками). Столбец Test_1 - это «A» в первой строке и «G» в 7-й строке, обе строки ввода имеют A равно 1, а B равно 1. Вы каким-то образом хотите агрегировать это до просто «G» — так что вам нужно чтобы использовать агрегатную функцию в select с group by - и вам нужно, чтобы эта функция выбирала "G", а не "A" в столбце Test_1. Точно так же, почему в столбце Test_5 выбрано «B», а не «H»? Обе строки 2 и 8 соответствуют оператору case Test_5.   -  person Gregor Thomas    schedule 24.08.2017
comment
Извинения. Я сделал опечатку в своей заявке. Отредактировал, чтобы исправить сейчас. Я хочу, чтобы результаты моего оператора select представляли собой одну строку, когда A = 1, и одну строку, когда A = 2. Затем я хочу выбрать A и различные соответствующие значения для A из Col в качестве дополнительных столбцов в том же операторе. Это имеет для вас больше смысла?   -  person Rtab    schedule 24.08.2017
comment
Точно так же вам понадобятся агрегатные функции для других столбцов, которые игнорируют значения NULL и выбирают имеющиеся значения. Вы можете использовать max() или min(), чтобы приблизиться к желаемому результату. max() выберет G вместо A и H вместо B, min сделает наоборот.   -  person Gregor Thomas    schedule 24.08.2017
comment
Просто используйте max() или min() вокруг ваших операторов case. Познакомьтесь с агрегатными функциями. Всякий раз, когда вы используете group by, каждый столбец в select должен либо частью группировки или результатом агрегата.   -  person Gregor Thomas    schedule 24.08.2017
comment
Попытаюсь. Спасибо, Грегор.   -  person Rtab    schedule 24.08.2017


Ответы (1)


Известная как условная агрегация в SQL (часто используется для поворота данных), поскольку комментарии @Gregor просто запускают агрегат, например MAX() (даже MIN() будет работать) вокруг операторов CASE:

SELECT A,
       MAX(CASE WHEN A = '1' AND B = '1' THEN Col ELSE NULL END) as Test_1, 
       MAX(CASE WHEN A = '1' AND B = '2' THEN Col ELSE NULL END) as Test_2, 
       MAX(CASE WHEN A = '1' AND B = '3' THEN Col ELSE NULL END) as Test_3, 
       MAX(CASE WHEN A = '2' AND B = '1' THEN Col ELSE NULL END) as Test_4, 
       MAX(CASE WHEN A = '2' AND B = '2' THEN Col ELSE NULL END) as Test_5, 
       MAX(CASE WHEN A = '2' AND B = '3' THEN Col ELSE NULL END) as Test_6
FROM DF
GROUP BY A
person Parfait    schedule 24.08.2017