我试图为Oracle 11g应用程序组织一个查询,并且遇到了问题。具有多个COUNT(DISTINCT xxx)的PL/SQL SELECT - 意外的结果
我就简化了真实的情景,使之更容易理解(也以保障客户的数据):
- 表A是基表。它有一个已知的标识符,我将它传递给查询。
- 对于表A中的每个条目,表B中可能有多个条目。表B包含我感兴趣的值。
- 对于表B中的每个条目,表C中也可能有多个条目。表C包含我感兴趣的另一个值
- 我也有一个XML片段,其中包含一个值列表,它可能与表C中的值相匹配,也可能不匹配。
- 查询执行外连接XML,这样如果有匹配的值,它会再次返回值,否则它是空的。
我想要做的是取回我传入的标识符,B和C中唯一值的计数,以及XML部分中唯一值(和非空值)的计数的加入。
我当前的查询是:
SELECT
a.ID
, COUNT(DISTINCT b.VAL) AS B_VAL
, COUNT(DISTINCT c.VAL) AS C_VAL
, COUNT(DISTINCT xml.VAL) AS XML_VAL
FROM a, b, c,
XMLTABLE('/field1/collection/value' passing my_xml_type
COLUMNS VAL VARCHAR2(50) PATH '.') xml
WHERE
a.ID = b.SOME_ID
AND b.OTHER_ID = c.OTHER_ID
AND c.VAL = xml.VAL (+)
现在,如果你忘了计数,只是返回行,一个例子结果集可能是这个样子:
ID B_VAL C_VAL XML_VAL
---------------------------------------
X abc 123 123
X abc 456 null
X abc 789 789
X abc 789 789
DESIRED:现在当我想做不同的计数时,我希望它能返回:
ID B_VAL C_VAL XML_VAL
---------------------------------------
X 1 3 2
实际:但是,这是我收到的时候我把它们都为COUNT(DISTINCT ...):
ID B_VAL C_VAL XML_VAL
---------------------------------------
X 1 1 1
替代方案: ...如果我走了DISTINCT随后的数,我得到:
ID B_VAL C_VAL XML_VAL
---------------------------------------
X 1 4 3
怎么来的DISTINCT似乎只在特定的B_VAL操作,但服用它导致它在所有行工作,但没有采取独特性考虑?
是否有另一种方法来做到这一点,不需要将所有连接复制为子查询?我完全错过了这一点吗?
(请注意,我不是一个数据库开发人员,我刚刚被拉进来帮忙,所以很抱歉如果这是一个简单的问题...我已经搜索谷歌并浏览本网站的答案但发布之前)!
谢谢。
我发现,如果我把XML表格加入了那么计数明显作品OK跨越B_VAL和C_VAL ...所以也许这是一个很奇怪的甲骨文如何处理XML表连接?
注意,我我发现如果我把XML表连接起来,那么在B_VAL和C_VAL之间的计数明显可以正常工作......对于Oracle如何处理XML表连接可能有些奇怪? – ChrisC 2011-06-08 06:37:37
鉴于下面的答案,您使用的是哪个版本的Oracle?文森特给出的测试案例是否也失败了? – 2011-06-08 12:03:11
@MikeyByCrikey,我现在在本地运行11.2.0.1,并且看到Vincent的不同结果。不幸的是,即使嵌套查询不适合我。此外,我需要找出目标生产数据库的版本,我不能只修补我的开发数据库... – ChrisC 2011-06-08 23:39:05