문제

다음 테이블이 주어지면 "항목"테이블의 모든 항목 목록을 포함하는 SQL 쿼리와 각 항목에 대해 "색상"테이블의 각 색상의 열을 포함하는 SQL 쿼리를 어떻게 작성할 수 있습니까? 항목은 관계가 있습니다.

그것이 명확하지 않다면, 어떤 추가 정보가 명확히하는 데 도움이 될지 알려주십시오. 테이블 정보 및 원하는 SQL 결과는 다음과 같습니다.

항목 테이블 :

id | item_name
1  | 'item 1'
2  | 'item 2'
3  | 'item 3'

색상 테이블 :

id | color_name
1  | 'red'
2  | 'blue'
3  | 'green'

item_color 테이블 :

item_id | color_id
1       | 1
1       | 3
2       | 2
2       | 3
3       | 2

원하는 SQL 쿼리 결과 :

item_name | red | blue | green
'item 1'  |  1  | null |   1
'item 2'  | null|   1  |   1
'item 3'  | null|   1  | null

감사합니다, 콜린

도움이 되었습니까?

해결책

사용:

SELECT item_name,
       MAX(red) 'red',
       MAX(blue) 'blue',
       MAX(green) 'green'
  FROM (SELECT t.item_name,
         CASE
           WHEN c.color_name = 'red' THEN
             1
           ELSE
             NULL
         END 'red',
         CASE
           WHEN c.color_name = 'blue' THEN
             1
           ELSE
             NULL
         END 'blue',
         CASE
           WHEN c.color_name = 'green' THEN
             1
           ELSE
             NULL
         END 'green'       
    FROM ITEMS t
    JOIN ITEM_COLOR ic ON ic.item_id = t.item_id
    JOIN COLORS c ON c.id = ic.color_id)
GROUP BY item_name 

항목과 관련된 총 #의 빨간색/파란색/녹색을 원할 경우 최대를 계산하도록 변경하십시오.

서브 쿼리 팩터링을 사용하여 대체 :

WITH icolors AS (
   SELECT t.item_name,
          CASE
           WHEN c.color_name = 'red' THEN
             1
           ELSE
             NULL
         END 'red',
     CASE
       WHEN c.color_name = 'blue' THEN
         1
       ELSE
         NULL
     END 'blue',
     CASE
       WHEN c.color_name = 'green' THEN
         1
       ELSE
             NULL
     END 'green'       
    FROM ITEMS t
    JOIN ITEM_COLOR ic ON ic.item_id = t.item_id
    JOIN COLORS c ON c.id = ic.color_id)
  SELECT t.item_name,
         MAX(t.red) 'red',
         MAX(t.blue) 'blue',
         MAX(t.green) 'green'
    FROM icolors t
GROUP BY t.item_name

다른 팁

당신은 Oracle 11g에 있습니까?

이것은 새로운 사람에게 이상적인 사용 인 것 같습니다. 피벗 11g의 기능

가능한 모든 색상을 미리 알고 있다면 지저분하지만 효과적으로 수행 할 수 있습니다. 가능한 모든 색상을 미리 알지 못하면 훨씬 더 어렵습니다. 결과 테이블에 어떤 열이 나타날 열을 찾은 다음 SQL을 제작하여 해당 열 (동적 SQL)을 만들어야합니다. .

결과 테이블의 열을 알고 있다고 가정 해 봅시다.

SELECT i.item_name, r.red, b.blue, g.green
  FROM items i
       LEFT JOIN
       (SELECT item_name, COUNT(*) AS red
          FROM item_color
         WHERE color_id = 1
         GROUP BY item_name) AS r
       ON i.item_name = r.item_name
       LEFT JOIN
       (SELECT item_name, COUNT(*) AS green
          FROM item_color
         WHERE color_id = 3
         GROUP BY item_name) AS g
       ON i.item_name = g.item_name
       LEFT JOIN
       (SELECT item_name, COUNT(*) AS blue
          FROM item_color
         WHERE color_id = 2
         GROUP BY item_name) AS b
       ON i.item_name = b.item_name

이 공식에서 나는 그림 물감 쿼리 빌드의 테이블. 대체 양식은 (내부)가 Colors 테이블에 결합하여 Clauses의 코드 대신 색상 이름을 사용하여 하위 쿼리를 작성합니다.

create table item (id number not null, item_name varchar2(200) not null);
create table color (id number not null, color_name varchar2(200) not null);
create table item_color (item_id number not null, color_id number not null);

insert into item values (1, 'item 1');
insert into item values (2, 'item 2');
insert into item values (3, 'item 3');


insert into color values (1, 'red');
insert into color values (2, 'blue');
insert into color values (3, 'green');

insert into item_color values (1, 1);
insert into item_color values (1, 3);
insert into item_color values (2, 2);
insert into item_color values (2, 3);
insert into item_color values (3, 2);

commit;

그런 다음 선택합니다.

select * from
(
select
  i.item_name
  , c.color_name
from
  item i
  , color c
  , item_color ic
where
  ic.item_id = i.id
  and ic.color_id = c.id
) pivot (
  count(color_name) cnt
  for color_name in ('red', 'blue', 'green')
);

제공 :

item 1    1    0    1
item 2    0    1    1
item 3    0    1    0

미리 색상 목록을 모르는 경우 먼저 색상 테이블을 선택한 다음 피벗 선택을 동적으로 빌드 할 수 있습니다 (Subselect : for color_name in (select color_name from color) 불가능합니다) 또는 또는 대안으로 사용할 수 있습니다 pivot xml 결과를 후 처리합니다.

select * from
(
select
  i.item_name
  , c.color_name
from
  item i
  , color c
  , item_color ic
where
  ic.item_id = i.id
  and ic.color_id = c.id
) pivot xml (
  count(color_name) cnt
  for color_name in (any)
)

제공 :

item 1  <PivotSet><item><column name = "COLOR_NAME">green</column><column name = "CNT">1</column></item><item><column name = "COLOR_NAME">red</column><column name = "CNT">1</column></item></PivotSet>
item 2  <PivotSet><item><column name = "COLOR_NAME">blue</column><column name = "CNT">1</column></item><item><column name = "COLOR_NAME">green</column><column name = "CNT">1</column></item></PivotSet>
item 3  <PivotSet><item><column name = "COLOR_NAME">blue</column><column name = "CNT">1</column></item></PivotSet>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top