2017-02-20 1 views
0

테이블을 감안할 때 : 나는 다른 말로 결과를SQL을 사용하여 그룹의 발생을 계산하고 두 개의 다른 열을 정렬되지 않은 세트로 처리하는 방법?

green,red: 3 
blue,red: 1 

을 좀하고 싶습니다

CREATE TABLE foo (
    thing_a VARCHAR2(15), 
    thing_b VARCHAR2(15) 
); 

그리고 행

INSERT INTO foo (thing_a, thing_b) VALUES 'red', 'green'; 
INSERT INTO foo (thing_a, thing_b) VALUES 'red', 'green'; 
INSERT INTO foo (thing_a, thing_b) VALUES 'green', 'red'; 
INSERT INTO foo (thing_a, thing_b) VALUES 'red', 'blue'; 

을, 나는 각각의 발생을 계산하고 싶습니다 thing_a와 thing_b의 그룹이지만 "빨강"과 "녹색"을 "녹색"과 "빨강"과 같다고 생각합니다.

나는 "솔루션"오셨습니다 가장 가까운 이것이다 :

greenred 
bluered 

그래서는 제대로 그룹화,하지만 아무것도 계산하지 않습니다 않습니다 산출

SELECT DISTINCT (
    CASE WHEN thing_a < thing_b 
    THEN thing_a || thing_b 
    ELSE thing_b || thing_a END 
) as thing FROM foo; 

.

해결 방법에 대한 제안 사항이 있으십니까?

답변

0

거의 다 왔어. 단순히 파생 테이블에 case 쿼리를 마무리하고 GROUP BY 그 결과,

select thing, count(*) 
from 
(
    SELECT CASE WHEN thing_a < thing_b THEN thing_a || thing_b 
      ELSE thing_b || thing_a 
      END as thing 
    FROM foo 
) dt 
group by thing 

너무 확실 AB와 CDE와 ABCD 전자와 혼동 같은 아이템은, 열 사이에 쉼표를 추가하지합니다. 파생 테이블에 UNION ALL을, 또는

select thing, count(*) 
from 
(
    SELECT CASE WHEN thing_a < thing_b THEN thing_a || ', ' || thing_b 
      ELSE thing_b || ', ' || thing_a 
      END as thing 
    FROM foo 
) dt 
group by thing 

를 (! 덕분에이 문제를 지적 mathguy합니다), 그리고 GROUP BY 그 결과,

select ta, tb, count(*) 
from 
(
    select thing_a as ta, thing_b as tb from foo where thing_a <= thing_b 
    union all 
    select thing_b, thing_a from foo where thing_a > thing_b 
) dt 
group by ta, tb 

ANSI SQL 규격 및 휴대용!

+0

@AugustLilleaas -이 답변을 "올바른"것으로 표시 했으므로 경험을 고려하면 놀랍습니다. 데이터에'('ab', 'cde')'와'('abcd', 'e')와 같은 정렬되지 않은 다음 집합이 있다고 가정합니다. 이 솔루션은 동일하게 취급합니다. – mathguy

+0

@mathguy, oops ... 내가 뭐라 할 수 있겠 니? a와 b 사이에 쉼표를 쉽게 추가 할 수있는 것처럼 보입니다. 몇 분 후에 다시 확인하십시오. – jarlh

+0

문자열 자체에 쉼표가 포함되어 있으면이 옵션이 작동하지 않습니다. – mathguy

1

이 모든 것은 하나의 SELECT 문에서 수행 할 수 있습니다. 최소값, 최대 값으로 그룹화하십시오. 참고 : 두 열 모두에 null이있을 경우에는 작동하지 않습니다. 이것이 가능하다면 질의는 좀 더주의해서 처리해야합니다.

with 
    foo (thing_a, thing_b) as (
     select 'red' , 'green' from dual union all 
     select 'red' , 'green' from dual union all 
     select 'green', 'red' from dual union all 
     select 'red' , 'blue' from dual union all 
     select 'ab' , 'cde' from dual union all 
     select 'abcd' , 'e'  from dual union all 
     select 'cde' , 'ab' from dual 
    ) 
-- end of test data; SQL query begins BELOW THIS LINE 
select least(thing_a, thing_b) as thing_a, greatest(thing_a, thing_b) as thing_b, 
     count(*) as cnt 
from foo 
group by least(thing_a, thing_b), greatest(thing_a, thing_b) 
order by thing_a, thing_b -- if needed 
; 

THING_A THING_B CNT 
------- ------- --- 
ab  cde  2 
abcd e   1 
blue red  1 
green red  3 

4 rows selected. 
+0

매우 흥미 롭습니다. 그룹별로 기능을 사용할 수 있는지 몰랐습니다! 내 데이터에 null이 없으므로 정상적으로 작동합니다. –

관련 문제