2010-09-03 52 views
1

正如标题所述,我想选择每队和每年的事件数。下面的select语句正常工作,但并不完全符合我的要求。Oracle SELECT:每队和每年的事件数

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 
; 

有了这个,如果我们有:

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

我们得到:

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

而且我想获得:

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

我不知道如何修改我的请求来这样做。

回答

1

我没有甲骨文这里测试,但一般这应该工作:

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 
; 

你会得到结果每一年,在那里你必须在事件的事件。如果这还不够,你可以用一个填满了所有年份的表格替换Years子。

+0

OP希望看到没有任何事件的年份,所以你不能依赖'EVENT'表。 – 2010-09-03 01:29:23

+0

因此是最后的评论。他没有说明顺便说一句,也可能是这样的情况,总有至少一个事件他想看到的年份(我无法知道:))。 – andrem 2010-09-03 01:39:24

2

用途:

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 

这将生成年份列表,但你必须设置:start_year:end_year绑定变量。

以前:

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即可获得一年,但返回它作为一个CHAR(4),所以你需要使用TO_NUMBER(TO_CHAR(date_col, 'yyyy'))得到的数字。所以我用EXTRACT,而不是...

+0

我希望它是自动的。我不想手写这些年。感谢提取提示。 – 2010-09-03 01:18:54

+0

该版本是Oracle 9i – 2010-09-03 01:24:24

+0

@Julio Guerra:Thx,请参阅更新。 – 2010-09-03 01:30:03

1

所以它的工作原理! :) 这是我的最终查询:

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 
; 

谢谢!