SQL查询自连接

时间:2011-04-29 14:53:49

标签: sql join oracle10g

我正在查询Oracle 10g中的报告。

我需要生成每个课程的简短列表以及过去一年中提供的课程次数(包括那些实际未提供的课程)。

我创建了一个查询

SELECT coursenumber, count(datestart) AS Offered
FROM class
WHERE datestart BETWEEN (sysdate-365) AND sysdate
GROUP BY coursenumber;

哪个产生

COURSENUMBER    OFFERED
----           ----------
ST03              2
PD01              1
AY03              2
TB01              4

此查询完全正确。但理想情况下,我希望它列出左侧列中的COURSENUMBER HY和CS以及0或null作为OFFERED值。我有一种感觉,这涉及各种各样的联合,但到目前为止,我所尝试的并没有产生没有提供任何东西的类。

该表通常看起来像

REFERENCE_NO DATESTART TIME TIME        EID     ROOMID COURSENUMBER
------------ --------- ---- ---- ---------- ---------- ----
         256 03-MAR-11 0930 1100          2          2 PD01
         257 03-MAY-11 0930 1100         12          7 PD01
         258 18-MAY-11 1230 0100         12          7 PD01
         259 24-OCT-11 1930 2015          6          2 CS01
         260 17-JUN-11 1130 1300          6          4 CS01
         261 25-MAY-11 1900 2000         13          6 HY01
         262 25-MAY-11 1900 2000         13          6 HY01
         263 04-APR-11 0930 1100         13          5 ST03
         264 13-SEP-11 1930 2100          6          4 ST03
         265 05-NOV-11 1930 2100          6          5 ST03
         266 04-FEB-11 1430 1600          6          5 ST03
         267 02-JAN-11 0630 0700         13          1 TB01
         268 01-FEB-11 0630 0700         13          1 TB01
         269 01-MAR-11 0630 0700         13          1 TB01
         270 01-APR-11 0630 0700         13          1 TB01
         271 01-MAY-11 0630 0700         13          1 TB01
         272 14-MAR-11 0830 0915          4          3 AY03
         273 19-APR-11 0930 1015          4          3 AY03
         274 17-JUN-11 0830 0915         14          3 AY03
         275 14-AUG-09 0930 1015         14          3 AY03
         276 03-MAY-09 0830 0915         14          3 AY03

3 个答案:

答案 0 :(得分:2)

SELECT
  coursenumber,
  COUNT(CASE WHEN datestart BETWEEN (sysdate-365) AND sysdate THEN 1 END) AS Offered
FROM class
GROUP BY coursenumber;

因此,正如您所看到的,此特定问题不需要连接。

答案 1 :(得分:1)

我觉得这样的事情应该对你有用,只需将其作为子查询。

SELECT distinct c.coursenumber, 
       (SELECT COUNT(*)
        FROM class
        WHERE class.coursenumber = c.coursenumber
          AND datestart BETWEEN (sysdate-365) AND sysdate
        ) AS Offered
FROM class c

答案 2 :(得分:1)

我更喜欢jschoen对这个特定情况的回答(当你想要主查询的每一行的子查询中只有一行和一列时),但只是为了演示另一种方法:

select t1.coursenumber, nvl(t2.cnt,0)
from class t1 left outer join (
 select coursenumber, count(*) cnt
 from class
 where datestart between (sysdate-365) AND sysdate
 group by coursenumber
) t2 on t1.coursenumber = t2.coursenumber