2013-07-01 2 views
0

두 테이블 table1과 table2가 있습니다. 나는 주제의 해마다 분포를 원한다. 주제 데이터를위한 두 번째 테이블을 만들었습니다. 임의의 테이블, table1 및 table2를 만들었습니다.여러 테이블에서 데이터를 가져 오기위한 MySql 쿼리

tabel1 

id | year 
1 | 2001 
2 | 2003 
3 | 2001 
4 | 2002 
5 | 2001 

나는, 공유 "ID"항목에 대한

table2 

id | topic | subtopic 
1 | sport | volley 
1 | water | ok 
1 | stock | apple 
2 | stock | us 
2 | stock | pine 
3 | world | uk 
3 | water | salt 
4 | water | sweet 
4 | world | ep 
5 | sport | volley 
5 | stock | apple 
5 | stock | pine 

TOP 범주 (= 1,2,5 3) 주식이고, 물 (= 1,3,4 세)와 두 번째 테이블이 스포츠 (2 = 1.5), 세계 (2 = 2,4)

그리고, 내가 너무 내 출력 데이터

 stock | water 
    ---------------- 
2001 2 | 2 
2002 0 | 1 
2003 1 | 0 

지금까지 일 것입니다 만 정상이 "항목"데이터를 원하는 말할 수 , 나는 그것을 위해 할 수 있었다. 개별 주제

SELECT table1.year AS YEAR, COUNT(DISTINCT table2.id) AS lcount 
FROM table1, table2 
WHERE topic = 'stock' 
AND table1.id = table2.id 
GROUP BY YEAR 

주제 만 4 국한되지 않습니다, N-다른 주제있을 수 있습니다. 그래서, n 개의 다른 주제가 발견되어야합니다. 나는 그들에게서 정상 2를 골라 내야한다.

+0

그리고 당신이 가지고있는 코드를 참조하십시오 : 당신은 값이나 반환됩니다 알 수없는 주제의 알 수없는 번호가있는 경우

는, 당신은 결과를 얻기 위해 동적 SQL을 사용해야합니다 지금까지 해봤습니까? .. – dbf

+1

이것은 group by 및 having 절에 대한 작업과 같습니다. 당신은 그것들을 조사해야합니다. – usumoio

+0

MySQL에는 내장 피벗 연산자가 없으므로 원하는 열을 미리 알지 못하면 피벗 테이블을 만들 수 없습니다. – Barmar

답변

2

당신은 당신의 결과를 얻을 수있는 CASE 표현식으로 집계 함수를 사용할 수 있습니다

select t1.year, 
    count(distinct case when topic = 'stock' then t2.id end) stock, 
    count(distinct case when topic = 'water' then t2.id end) water, 
    count(distinct case when topic = 'sport' then t2.id end) sport, 
    count(distinct case when topic = 'world' then t2.id end) world 
from table1 t1 
left join table2 t2 
    on t1.id = t2.id 
group by t1.year; 

SQL Fiddle with Demo를 참조하십시오.

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'count(distinct CASE WHEN topic = ''', 
     topic, 
     ''' THEN t2.id END) AS `', 
     topic, '`' 
    ) 
) INTO @sql 
FROM 
(
    select count(distinct id) total, topic 
    from table2 
    group by topic 
    order by total desc 
    limit 2 
) d; 

SET @sql 
    = CONCAT('SELECT t1.year, ', @sql, ' 
      from table1 t1 
      left join table2 t2 
       on t1.id = t2.id 
      group by t1.year'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

SQL Fiddle with Demo

+0

주식 (3 = 1,2,5), 물 (3 = 1,3,4), 스포츠 (2 = 1,5), 세계 (2 = 2,4)가 자동으로 결정됩니다. 주제는 4 가지로 제한되지 않으며, n 가지 다른 주제가있을 수 있습니다. 나는 그들에게서 정상 2를 골라 내야한다. – Zero

+0

@JohnGalt 동적 SQL 버전을 포함하도록 내 대답을 편집했습니다. – Taryn

+0

결과는 (스포츠, 물)로오고 있지만 (스톡 | 물) 맞아야합니까? – Zero

0

이 안된이지만, 트릭 수행해야합니다

SELECT a.`year`, 
    COALESCE(b_stock.rec_count, 0) as `stock`, 
    COALESCE(b_water.rec_count, 0) as `water` 
FROM table1 a 
LEFT JOIN (
    SELECT b2.`year`, COUNT(b.*) as rec_count 
    FROM table2 b 
    JOIN table1 b2 ON b2.id = b.id 
    WHERE b.topic = 'stock' 
    GROUP BY b2.year 
) b_stock ON b_stock.`year` = a.`year` 
LEFT JOIN (
    SELECT b2.`year`, COUNT(b.*) as rec_count 
    FROM table2 b 
    JOIN table1 b2 ON b2.id = b.id 
    WHERE b.topic = 'water' 
    GROUP BY b2.year 
) b_water ON b_water.`year` = a.`year` 
GROUP BY a.`year` 
ORDER BY a.`year` 
+0

'주식'과 '물'을 결정해야합니다. 또한 상위 2 항목입니다. – Zero

+0

@JohnGalt 얼마나 많은 종류의 주제가 있습니까? 소수의 경우에만 조인을 추가하여 하나의 쿼리에서 모든 항목의 수를 구할 수 있으며 그 시점부터 ORDER BY를 사용하여 어떤 항목이 최상위 항목인지 확인할 수 있습니다. – Seth

관련 문제