2016-05-07 8 views
3

Я хотел бы группе (а, б) и (Ь, а) в одну группу (а, б) в SQLГруппировка пар в SQL

Для получения, например, следующий набор

SELECT 'a' AS Col1, 'b' AS Col2 
UNION ALL 
SELECT 'b', 'a' 
UNION ALL 
SELECT 'c', 'd' 
UNION ALL 
SELECT 'a', 'c' 
UNION ALL 
SELECT 'a', 'd' 
UNION ALL 
SELECT 'b', 'c' 
UNION ALL 
SELECT 'd', 'a' 

должны давать

Col1 | Col2 
a  b 
c  d 
a  c 
a  d 
b  c 

ответ

4

Группа по сазе, который выбирает пары в алфавитном порядке:

select case when col1 < col2 then col1 else col2 end as col1, 
case when col1 < col2 then col2 else col1 end as col2 
from (
    select 'a' as col1, 'b' as col2 
    union all 
    select 'b', 'a' 
    union all 
    select 'c', 'd' 
    union all 
    select 'a', 'c' 
    union all 
    select 'a', 'd' 
    union all 
    select 'b', 'c' 
    union all 
    select 'd', 'a' 
) t group by case when col1 < col2 then col1 else col2 end, 
case when col1 < col2 then col2 else col1 end 

http://sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/6977

Если вы хотите просто уникальные значения (в отличие от группировки для агрегации), то вы можете использовать distinct вместо group by

select distinct case when col1 < col2 then col1 else col2 end as col1, 
case when col1 < col2 then col2 else col1 end as col2 
from (
    select 'a' as col1, 'b' as col2 
    union all 
    select 'b', 'a' 
    union all 
    select 'c', 'd' 
    union all 
    select 'a', 'c' 
    union all 
    select 'a', 'd' 
    union all 
    select 'b', 'c' 
    union all 
    select 'd', 'a' 
) t 
2

В качестве альтернативы можно использовать UNION для достижения этой цели:

WITH cte AS (
    SELECT 'a' AS Col1, 'b' AS Col2 
    UNION ALL 
    SELECT 'b', 'a' 
    UNION ALL 
    SELECT 'c', 'd' 
    UNION ALL 
    SELECT 'a', 'c' 
    UNION ALL 
    SELECT 'a', 'd' 
    UNION ALL 
    SELECT 'b', 'c' 
    UNION ALL 
    SELECT 'd', 'a') 
SELECT col1, col2 FROM cte WHERE col1 < col2 OR col1 IS NULL 
UNION 
SELECT col2, col1 FROM cte WHERE col1 >= col2 OR col2 IS NULL 
ORDER BY 1, 2 

SQL fiddle

Обратите внимание, что UNION удаляет дубликаты.

Если у вас нет значений NULL, вы можете, конечно, опустить часть OR в предложениях WHERE.

0

По значению (a, b) не равно (b, a). Если вы хотите относиться к ним одинаково, вы создаете новые ключевые столбцы для каждой строки. Общая логика будет

WITH TableWithNewKey 
(
    SELECT <original columns>, <new columns as key> 
    FROM originaltable 
) 
SELECT <new columns as key>, Aggregate(...) 
FROM TableWithNewKey 
GROUP BY <new columns as key> 

В вашем случае <new columns as key> для преобразования (Ь, а) (а, б). Это может быть аргумент case для замены a и b или других функций. Эта форма применяется к любому количеству столбцов и другому сопоставлению равенства.

0
select col1, col2 from table 
except 
select col2, col2 from table where col2 > col1 
Смежные вопросы