2010-09-03 5 views
1

Comme indiqué dans le titre, je veux sélectionner le nombre d'événements par équipe et par an. L'instruction select ci-dessous fonctionne bien mais ne me donne pas exactement ce que je cherche.Oracle SELECT: nombre d'événements par équipe et par an

SELECT 
Team.team_id, 
TO_CHAR(Event.START_DATE_TIME, 'yyyy') AS year, 
count(event_id) AS events 
FROM 
Team 
LEFT OUTER JOIN 
Event ON Event.team_id = Team.team_id 
GROUP BY 
TO_CHAR(Event.START_DATE_TIME, 'yyyy'), 
team_id 
ORDER BY 
year ASC, 
team_id ASC 
; 

Avec cela, si nous avons:

Team 1 : 1 event in 2006 
Team 2 : 1 event in 2007 

Nous obtenons:

ID | Year | Events 
------------------ 
1 | 2006 | 1 
2 | 2007 | 1 

et je voudrais obtenir:

ID | Year | Events 
------------------- 
1 | 2006 | 1 
2 | 2006 | 0 
1 | 2007 | 0 
2 | 2007 | 1 

Je ne sais pas comment modifier ma demande pour le faire.

Répondre

1

Je ne l'ai pas Oracle ici pour tester, mais en général cela devrait fonctionner:

SELECT 
Team.team_id, 
Years.year, 
COALESCE(count(Event.event_id),0) events 
FROM 
Team 
    JOIN (SELECT DISTINCT EXTRACT(YEAR FROM start_date_time) year FROM Event) Years ON 1=1 
    LEFT OUTER JOIN Event ON Event.team_id = Team.team_id AND EXTRACT(YEAR FROM Event.start_date_time) = Years.year 
GROUP BY 
Years.year, 
team_id 
ORDER BY 
year ASC, 
team_id ASC 
; 

Vous obtiendrez des résultats pour chaque année où vous avez un événement dans les événements . Si cela ne suffit pas, vous pouvez remplacer le sous-titre Années par un tableau rempli de toutes les années.

+0

L'OP veut voir les années pour lesquelles il n'y a aucun événement, donc vous ne pouvez pas compter sur la table 'EVENT'. –

+0

D'où le dernier commentaire. Il n'a pas dit ça, et il se peut aussi qu'il y ait toujours au moins un événement pour les années qu'il veut voir (je n'ai aucun moyen de le savoir :)). – andrem

2

Utilisation:

SELECT x.team_id, 
      x.year, 
      COALESCE(COUNT(e.event_id), 0) AS events 
    FROM (SELECT :start_year + LEVEL - 1 AS year, 
        t.team_id 
      FROM DUAL, TEAM t 
     CONNECT BY :start_year + LEVEL - 1 <= :end_year) x 
LEFT JOIN EVENT e ON EXTRACT(YEAR FROM e.start_date_time) = x.year 
       AND e.team_id = x.team_id 

Cela va générer une liste d'années, mais vous devez définir les :start_year et :end_year variables BIND.

Auparavant:

SELECT x.team_id, 
      x.year, 
      COALESCE(COUNT(e.event_id), 0) AS events 
    FROM (SELECT 2006 AS year, 
        a.team_id 
      FROM TEAM a 
      UNION ALL 
      SELECT 2007, 
        b.team_id 
      FROM TEAM b) x 
LEFT JOIN EVENT e ON EXTRACT(YEAR FROM e.start_date_time) = x.year 
       AND e.team_id = x.team_id 

TO_CHAR est OK pour obtenir l'année, mais il revient en tant que CHAR (4), vous devez utiliser TO_NUMBER(TO_CHAR(date_col, 'yyyy')) pour obtenir un numéro. Donc, je EXTRACT à la place ...

+0

Je veux que ce soit automatique. Je ne veux pas écrire les années à la main. Merci pour le conseil avec extrait. –

+0

La version est Oracle 9i –

+0

@Julio Guerra: Thx, voir mise à jour. –

1

Alors ça marche! :) Voici ma dernière question:

SELECT 
Team.name, 
Years.year, 
count(Event.event_id) 
FROM 
    Team 
JOIN 
    (
     SELECT DISTINCT EXTRACT(YEAR FROM start_date_time) AS year 
     FROM Event 
    ) Years ON 1 = 1 
LEFT OUTER JOIN 
    Event ON Event.team_id = Team.team_id 
       AND EXTRACT(YEAR FROM Event.start_date_time) = Years.year 
WHERE 
    event_type = 'C' 
GROUP BY 
    Team.name, 
    Years.year 
ORDER BY 
    Year ASC, 
    name ASC 
; 

Merci!

Questions connexes