我在这个论坛上看到关于同一主题的不同问题,一个罐装且频繁出现的回复是:
不,Oracle没有关联嵌套多个级别的子查询(MySQL也没有)。
我将从中得出结论,Oracle确实将一个子查询关联到一个层次。但是,我有以下查询,它返回此错误消息:
ORA-00904:“CD”。“FIELD6”:无效标识符
此查询非常重要,并且只是涉及UNION语句的实际查询的简化版本。在调试返回错误消息的原因时,我将其缩减为最简单的版本(如下所示)。我意识到这个最简单的版本可能有替代的JOIN方法,但这种替代方法不适用于实际查询。如果以下可以工作,那么看起来我们更复杂的查询也可以工作。如果以下内容无效,那么我在Oracle的文档和上面的“预制”答案中读取的内容是错误的?
SELECT a.*
FROM
main_detail cd INNER JOIN
(
SELECT
Field1,
Field2,
Field3,
Field4,
Field5,
Field6,
Field7
FROM other_detail x2
WHERE x2.Field1 = cd.Field1 AND x2.Field6 = cd.Field6
) a ON
a.Field1 = cd.Field1
AND a.Field4 = cd.Field4
AND a.Field6 = cd.Field6
以下更类似于我们的实际需要。 UNION需要保持返回的UNION-ed集合上的JOIN,因为它被用作INNER JOIN来限制返回记录集:
SELECT h.*, a.*
FROM
header h,
(
SELECT
Field1,
Field2,
Field3,
Field4,
Field5,
Field6,
Field7
FROM main_detail x1
WHERE x1.Field1 = h.Field1 AND x1.Field6 = h.Field6
UNION
SELECT
Field1,
Field2,
Field3,
Field4,
Field5,
Field6,
Field7
FROM other_detail x2
WHERE x2.Field1 = h.Field1 AND x2.Field6 = h.Field6
) a
WHERE
a.Field1 = h.Field1 AND
a.Field6 = h.Field6
当将上述内容与不包括相关子查询参数进行比较,并在MS SQL中测试运行时,它将性能从9分钟提高到30-40秒,这是一个非常可观的改进。我希望在Oracle中获得同样的收益。
以下是我对实际代码的尽可能接近,而不会影响客户端的机密性:
SELECT DISTINCT
c.Field1,
c.Field2,
D.Field3,
b.Field4,
b.Field5,
c.Field6,
c.Field7 || '-' || cds1.Field8 AS status,
b.paid,
cds.Field8,
p.Field9,
p.Field10,
c.Field11,
c.Field12 AS provider_name
FROM
header c,
(
SELECT
a.*,
cd.paid,
cd.Field15,
cd.BigList,
cd.allowed,
cd.copayment,
cd.coinsurance
FROM
header_detail cd,
(
SELECT
Field1,
Field4,
'' AS revenue_code,
Field20,
Field5,
Field14,
location_code,
ServiceList
FROM header_other_detail x1
WHERE x1.Field1 = cd.Field1 AND x1.Field14 = cd.Field14
UNION
SELECT
Field1,
Field4,
revenue_code,
Field20,
Field5,
Field14,
'' AS location_code,
ServiceList
FROM inst_claim_detail x2
WHERE x2.Field1 = cd.Field1 AND x2.Field14 = cd.Field14
) a
WHERE
a.Field1 = cd.Field1
AND cd.Field1 = c.Field1
AND a.Field20 = cd.Field20
AND a.Field14 = cd.Field14
AND cd.Field14 = c.Field14a
) b,
(
SELECT
Field1,
Field14,
Trim(
Trailing ',' FROM
ch.icd9_1 || ',' ||
ch.icd9_2 || ',' ||
ch.icd9_3 || ',' ||
ch.icd9_4 || ',' ||
ch.icd9_5 || ',' ||
ch.icd9_6 || ',' ||
ch.icd9_7 || ',' ||
ch.icd9_8 || ',' ||
ch.icd9_9 || ',' ||
ch.icd9_10 || ',' ||
ch.icd9_11 || ',' ||
ch.icd9_12
)
AS Field3
FROM prof_claim ch
WHERE ch.Field1 = c.Field1 AND ch.Field14 = c.Field14a
UNION
SELECT
Field1,
Field14,
Field3
FROM inst_claim x3
WHERE x3.Field1 = c.Field1 AND x3.Field14 = c.Field14a
) d,
(
SELECT
Field1,
Field14,
Field9,
Field10,
Field18,
refund_amount,
Field15
FROM payment_detail
) p,
(SELECT * FROM Codes WHERE code_type='19') cds,
(SELECT * FROM Codes WHERE code_type='28') cds1
WHERE
c.Field17 = 'T00000370'
AND c.Field1 = b.Field1 AND c.Field14a = b.Field14
AND c.Field1 = d.Field1 AND c.Field14a = d.Field14
AND b.Field14 = p.Field14(+) AND b.Field1 = p.Field1(+) AND b.Field15 = p.Field15(+)
AND b.BigList = cds.Field16(+) AND b.Field14 = cds.Field14(+)
AND c.Field7 = cds1.Field16(+) AND c.Field14a = cds1.Field14(+)
ORDER BY Field1;
答案 0 :(得分:1)
在子查询中
SELECT
Field1,
Field2,
Field3,
Field4,
Field5,
Field6,
Field7
FROM other_detail x2
WHERE x2.Field1 = cd.Field1 AND x2.Field6 = cd.Field6
检查where条件。如果完全删除或至少删除了cd
引用 - 查询可以正常工作。
答案 1 :(得分:0)
如果要将子查询加入表(或其他子查询),则所有连接条件必须位于ON
子句中,如果您使用的是ANSI样式连接。
您的查询失败的原因是a
子查询的范围不会扩展到自身之外。它完全独立于main_detail表的范围,因为您尝试连接表,而不是关联它们。正如Marmite Bomber的回答所示,子查询需要能够独立运行,而你的尝试版本却没有。
您需要做的是将相关过滤器移动到ON
子句,如下所示:
SELECT a.*
FROM
main_detail cd INNER JOIN
(
SELECT
Field1,
Field2,
Field3,
Field4,
Field5,
Field6,
Field7
FROM other_detail x2) a ON
a.Field1 = cd.Field1
AND a.Field4 = cd.Field4
AND a.Field6 = cd.Field6
and a.Field1 = cd.Field1 AND a.Field6 = cd.Field6
当然,它与:
相同SELECT a.*
FROM
main_detail cd INNER JOIN
other_detail a ON
a.Field1 = cd.Field1
AND a.Field4 = cd.Field4
AND a.Field6 = cd.Field6
关于您使用UNION的查询,这应该有助于您比原始查询带来一些性能优势:
SELECT *
FROM (SELECT h1.*,
x1.field1,
x1.field2,
x1.field3,
x1.field4,
x1.field5,
x1.field6,
x1.field7
FROM main_detail x1
inner join header h1 on (x1.Field1 = h1.Field1 AND x1.Field6 = h1.Field6)
UNION
SELECT h2.*
field1,
field2,
field3,
field4,
field5,
field6,
field7
FROM other_detail x2
inner join header h2 on (x2.Field1 = h2.Field1 AND x2.Field6 = h2.Field6));