2015-09-25 121 views
0

我正在使用以下CTE。第一部分收集所有独特的人,第二部分在特定的时间框架内加入独特的人与事件。我期望所有的行都会从我的唯一人员表中返回,即使他们在时间范围内没有事件。但这似乎并非如此。Oracle左连接不返回所有行

WITH DISTINCT_ATTENDING(ATTENDING) AS 
(
SELECT DISTINCT ATTENDING 
FROM PEOPLE 
WHERE ATTENDING IS NOT NULL 
), -- returns 62 records 
EVENT_HISTORY(ATTENDING, TOTAL) AS 
(
SELECT C.ATTENDING, 
     COUNT(C.ID) 
FROM DISTINCT_ATTENDING D 
LEFT JOIN PEOPLE C 
ON C.ATTENDING = D.ATTENDING 
AND TO_DATE(C.DATE, 'YYYYMMDD') < TO_DATE('20140101', 'YYYYMMDD') 

GROUP BY C.ATTENDING 
ORDER BY C.ATTENDING 

) 

SELECT * FROM EVENT_HISTORY; -- returns 49 rows 

我在这里做错了什么?

+2

如果您删除'AND TO_DATE(C.DATE,'YYYYMMDD')

+0

@vkp我得到62行返回。起初,我在那里有一个where子句,并认为这是导致问题的原因。 – Jonnny

+0

将LEFT JOIN切换到右连接? – jarlh

回答

1

强尼

的问题是在矿井列 “C.ATTENDING”,只是改变了 “D.ATTENDING”

SELECT D.ATTENDING, 
     COUNT(C.ID) 
FROM DISTINCT_ATTENDING D 
LEFT JOIN PEOPLE C 
ON C.ATTENDING = D.ATTENDING 
AND TO_DATE(C.DATE, 'YYYYMMDD') < TO_DATE('20140101', 'YYYYMMDD') 

GROUP BY D.ATTENDING 
ORDER BY D.ATTENDING 
+0

谢谢 - 从来没有想过列,只是假设我正在构建连接不正确。 – Jonnny

+1

更改“群”和“秩序”=) –

1

您的查询显得过于复杂。我认为有以下做同样的事情:

SELECT P.ATTENDING, 
     SUM(CASE WHEN TO_DATE(P.DATE, 'YYYYMMDD') < TO_DATE('20140101', 'YYYYMMDD') 
       THEN 1 ELSE 0 END) 
FROM PEOPLE P 
WHERE P.ATTENDING IS NOT NLL 
GROUP BY P.ATTENDING 
ORDER BY P.ATTENDING ; 

你的问题是,你被列在left join的聚集。当没有匹配时,这是NULL

+0

谢谢戈登 - 我同意这个问题,我是你的答案的忠实粉丝:-)我正在建立几个列到这个到最后输出一个数据集。我发现CTE比多个子查询更容易阅读。所以它不会是返回的最终结束数据集。但是我很早就遇到了这个问题。我将以总计,平均数和%s返回9-10列。 CTE是一个不错的想法,或者你会提出另一种方法吗? – Jonnny

+1

@Jonnny。 。 。 CTE很好。但是,你应该使用'group by'来总结'people',并从那个表中获得你想要的字段。我想我明白你为什么要做'左连接',但我仍然觉得很尴尬(而额外的工作会影响性能)。 –

+0

感谢您的帮助:-) – Jonnny