2013-07-01 9 views
0

J'ai deux tables table1 et table2. Je veux obtenir la distribution annuelle des sujets. J'ai fait une deuxième table pour les données de sujet. J'ai créé des tables aléatoires, table1 et table2.Requête MySql pour extraire des données de plusieurs tables

tabel1 

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

J'ai deuxième table avec Partagée "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 

catégories TOP pour le sujet sont disponibles (3 = 1,2,5), l'eau (3 = 1,3,4), sport (2 = 1,5), monde (2 = 2,4)

Et, disons que je ne veux que deux top "topic" données ainsi, mes données de sortie seraient

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

jusqu'à présent , J'ai réussi à le faire pour sujet individuel

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 

Les sujets ne sont pas limités à seulement 4, il peut y avoir n-sujets différents. Donc, n-différents sujets doivent être trouvés. J'ai besoin de choisir le top 2 d'eux.

+0

Et le code que vous avez essayé jusqu'à présent est? .. – dbf

+1

Cela ressemble à un travail pour les clauses group by et having. vous devriez regarder dans ceux-ci. – usumoio

+0

MySQL ne dispose pas d'un opérateur de pivot intégré, vous ne pouvez donc pas créer de tableau croisé dynamique à moins de connaître au préalable les colonnes que vous souhaitez. – Barmar

Répondre

2

Vous pouvez utiliser une fonction d'agrégation avec une expression CASE pour obtenir votre résultat:

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; 

Voir SQL Fiddle with Demo.

Si vous avez un nombre inconnu de valeurs ou des sujets inconnus qui seront retournés, alors vous devrez utiliser SQL dynamique pour obtenir le résultat:

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; 

Voir SQL Fiddle with Demo

+0

stock (3 = 1,2,5), eau (3 = 1,3,4), sport (2 = 1,5), monde (2 = 2,4) sont à déterminer automatiquement. Les sujets ne sont pas limités à seulement 4, il peut y avoir n sujets différents. J'ai besoin de choisir le top 2 d'eux. – Zero

+0

@JohnGalt J'ai édité ma réponse pour inclure une version dynamique de sql. – Taryn

+0

Le résultat s'apprête comme suit (SPORT, EAU) mais il devrait être (stock | eau) non? – Zero

0

Ce n'est pas testé, mais devrait faire l'affaire:

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

J'ai besoin de déterminer «stock» et «l'eau» sont les 2 principaux sujets aussi automatiquement. – Zero

+0

@JohnGalt combien de types de sujets aurez-vous? Si vous n'en avez qu'une poignée, vous pouvez ajouter quelques jointures supplémentaires pour obtenir le nombre de rubriques pour toutes les rubriques dans une requête, et à partir de ce point, vous pouvez voir celles qui sont le sujet principal en utilisant ORDER BY. – Seth

Questions connexes