MySql查询从多个表中提取数据

时间:2013-07-01 19:34:50

标签: mysql pivot

我有两个表table1和table2。我想要按年分配主题。我为主题数据制作了第二个表格。我创建了随机表table1和table2。

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个不同的主题。我需要从他们那里挑选前2名。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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`