여러 테이블에서 SQL 쿼리를 구축하는 데 도움이됩니다
문제
다음 테이블이 주어지면 "항목"테이블의 모든 항목 목록을 포함하는 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>