2013-07-01 44 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類別主題是股票(3 = 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個不同的主題。我需要從他們中挑選前兩名。

+0

而你的代碼到目前爲止嘗試的是? .. – dbf

+1

這看起來像一個團隊工作,並有條款。你應該看看那些。 – usumoio

+0

MySQL沒有內置的pivot操作符,因此除非事先知道所需的列,否則不能創建數據透視表。 – 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

如果你有一個未知的數值或將返回未知的話題,那麼你將不得不使用動態SQL來得到結果:

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個不同的主題。我需要從他們中挑選前兩名。 – Zero

+0

@JohnGalt我編輯我的答案,包括一個動態的sql版本。 – Taryn

+0

結果即將到來(SPORT,WATER),但它應該是(stock | water)對嗎? – 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