假设我们有这样的查询:
SELECT
tt.id first_column,
tt.value second_column,
--another values
qq.code_1 third_column,
qq.code_2 column4,
qq.code_3 column5,
qq.code_4 column6,
qq.code_5 column7
FROM
test_tbl tt LEFT JOIN
(SELECT * FROM (
SELECT id, code_value, ROW_NUMBER() OVER (ORDER BY code_value) AS RN
FROM attributes attr WHERE attr.id = tt.id AND
attr.code IN ('ATTRIBUTE_CODE_1',
'ATTRIBUTE_CODE_2',
'ATTRIBUTE_CODE_3',
'ATTRIBUTE_CODE_4',
'ATTRIBUTE_CODE_5')
)
PIVOT (MAX(code_value) FOR (RN) IN (1 as code_1, 2 as code_2, 3 as code_3, 4 as code_4, 5 as code_5))) qq
ON tt.id = qq.id
-- LEFT JOINS with another tables...
问题是错误:
ORA-00904: "TT"."ID": invalid identifier
我怎样才能绕过这个障碍?
当然上面的例子很容易和虚拟,真正的查询更复杂。
此示例可在此处查看:http://sqlfiddle.com/#!4/eec83/3
答案 0 :(得分:1)
只需删除有问题的条件:
WHERE attr.id = tt.id
...但为确保RN
值正确,您还需要在partition by id
条款中添加row_number() over
。
ROW_NUMBER() OVER (PARTITION BY id ORDER BY code_value) AS RN
SELECT
tt.id first_column,
tt.value second_column,
--another values
qq.code_1 third_column,
qq.code_2 column4,
qq.code_3 column5,
qq.code_4 column6,
qq.code_5 column7
FROM
test_tbl tt LEFT JOIN
(SELECT * FROM (
SELECT id, code_value, ROW_NUMBER() OVER (partition by id ORDER BY code_value) AS RN
FROM attributes attr WHERE
attr.code IN ('ATTRIBUTE_CODE_1',
'ATTRIBUTE_CODE_2',
'ATTRIBUTE_CODE_3',
'ATTRIBUTE_CODE_4',
'ATTRIBUTE_CODE_5')
)
PIVOT (MAX(code_value) FOR (RN) IN (1 as code_1, 2 as code_2, 3 as code_3, 4 as code_4, 5 as code_5))) qq
ON tt.id = qq.id
答案 1 :(得分:1)
您无法在内联视图中引用其他表/视图。我找不到一个说明这一点的文档,但就是这样。这是设计,查询优化器如何处理查询。
使用这个简单的查询,实际情况更为明显:
SELECT
*
FROM
test_tbl tt ,
(
SELECT ID, CODE_VALUE
FROM attributes attr
WHERE attr.id = tt.id
) qq
错误:
ORA-00904: "TT"."ID": invalid identifier
如果要进行连接,则应使用JOIN
并将条件放在ON子句中,或将条件放在WHERE子句中以加入内联视图和表。
像这里:
SELECT
*
FROM
test_tbl tt ,
(
SELECT ID, CODE_VALUE
FROM attributes attr
) qq
WHERE attr.id = tt.id
或者查看您是否要制作CROSS APPLY
。这似乎是一个加入。
另见answer,有一个很好的表达方式:
内联视图/派生表在查询开头创建一个临时的未命名视图,然后将其视为另一个表,直到操作完成。因为编译器在查看FROM行上的这些子查询时需要创建一个临时视图,所以这些子查询必须完全是自包含的,而子查询之外没有引用。
我相信并非总是如此,在某些情况下,oracle可以选择合并内联视图。并且可以通过使用NO_MERGE优化器提示强制合并。
我打算尽快添加查询计划,这可能会提供更多的想法
答案 2 :(得分:0)
您可以从内部子查询中删除该条件,因为它没有任何意义,因为您已经在其公共列id
上的两个表上都留下了外部联接。
您可以在下面对查询进行更改。
SELECT
tt.id first_column,
tt.value second_column,
qq.code_1 third_column,
qq.code_2 column4,
qq.code_3 column5,
qq.code_4 column6,
qq.code_5 column7
FROM
test_tbl tt LEFT JOIN
(SELECT * FROM (
SELECT id, code_value, ROW_NUMBER() OVER (ORDER BY code_value) AS RN
FROM attributes attr WHERE
attr.code IN ('ATTRIBUTE_CODE_1',
'ATTRIBUTE_CODE_2',
'ATTRIBUTE_CODE_3',
'ATTRIBUTE_CODE_4',
'ATTRIBUTE_CODE_5')
)
PIVOT (MAX(code_value) FOR (RN)
IN (1 as code_1, 2 as code_2, 3 as code_3, 4 as code_4, 5 as code_5))) qq
ON tt.id = qq.id;
愿这对你有所帮助。