2017-02-03 9 views
1

Извините за плохой заголовок. Я не мог придумать лучшего способа описать мою проблему.SQL GROUP BY с столбцами, которые содержат зеркальные значения

У меня есть следующая таблица:

Category | A | B 
A  | 1 | 2 
A  | 2 | 1 
B  | 3 | 4 
B  | 4 | 3 

Я хотел бы, чтобы сгруппировать данные по Category, возвращать только 1 строку в каждой категории, но предоставить оба значения столбцов A и B.

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

category | resultA | resultB 
A  | 1  | 2 
B  | 4  | 3 

Как это может быть достигнуто?

Я попытался это заявление:

SELECT category, a, b 
FROM table 
GROUP BY category 

но, очевидно, я получаю следующие ошибки:

Колонка «а» недопустим в списке выбора, поскольку он не содержится в либо агрегатная функция или предложение GROUP BY.

Столбец «b» недействителен в списке выбора, поскольку он не содержится ни в агрегатной функции , ни в предложении GROUP BY.

Как достичь желаемого результата?

+0

Можете ли вы объяснить ваш ожидаемый результат немного больше? почему A = 1, 4 сохранено и 2, 3 удалено? Вы хотите сохранить одну строку для каждой категории? – GurV

+0

Каковы критерии для выбора значений в a и b, которые вы хотите отобразить? – Simon

+0

И если есть три строки с категорией А, с этой парой {5, 5}, каков будет ваш результат? –

ответ

3

Попробуйте это:

SELECT category, MIN(a) AS resultA, MAX(a) AS resultB 
FROM table 
GROUP BY category 

Если значения зеркально, то вы можете получить оба значения, используя MIN, MAX применяется на один столбец, такой как a.

+2

Это не будет генерировать ожидаемый результат (что, по общему признанию, не имеет смысла). –

+0

Это не обеспечивает выходы из столбцов a и b и не решает вопрос о том, какие значения возвращаются. – Simon

+0

@Simon На самом деле, я думаю, что это действительно может быть то, что хочет OP, но оно не будет соответствовать ожидаемому результату. –

2

Принимая во внимание случайную запись из дубликатов для каждого category.

Вот один трюк, с помощью таблицы значных конструктор и Row_Number оконной функции

;with cte as 
(
SELECT *, 
     (SELECT Min(min_val) FROM (VALUES (a),(b))tc(min_val)) min_val, 
     (SELECT Max(max_val) FROM (VALUES (a),(b))tc(max_val)) max_val 
FROM (VALUES ('A',1,2), 
       ('A',2,1), 
       ('B',3,4), 
       ('B',4,3)) tc(Category, A, B) 
) 
select Category,A,B from 
(
Select Row_Number()Over(Partition by category,max_val,max_val order by (select NULL)) as Rn,* 
From cte 
) A 
Where Rn = 1 
3

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

Рассматривается пара (x, y), равная паре (y, x). Чтобы найти дубликаты, вы можете поставить более низкое значение, в первую очередь, и тем больше, во втором, а затем применить DISTINCT на строках:

select distinct 
    category, 
    case when a < b then a else b end as attr1, 
    case when a < b then b else a end as attr2 
from mytable; 
+0

Интересный логический коммутатор, но также возвратит не зеркало –