由于一些动态SQL的复杂性,我需要将两个表连接在一起并从结果中查询,就好像它是一个表一样。扭曲的是我必须SELECT *
对内部查询 - 我不能对列进行别名。似乎没有办法在外部查询中识别这些列。
以这些表格为例
CREATE TABLE test_tab1 (join_key NUMBER, tab1_uqcol VARCHAR2(30));
CREATE TABLE test_tab2 (join_key NUMBER, tab2_uqcol VARCHAR2(30));
INSERT INTO test_tab1 VALUES (1, 'table 1 only');
INSERT INTO test_tab2 VALUES (1, 'table 2 only');
我可以轻松地对其唯一列进行过滤
SELECT *
FROM (
SELECT *
FROM test_tab1 t1
INNER JOIN test_tab2 t2
ON t1.join_key = t2.join_key
) joined
WHERE tab1_uqcol LIKE 'table%';
但如果我尝试引用他们共同的专栏......
SELECT *
FROM (
SELECT *
FROM test_tab1 t1
INNER JOIN test_tab2 t2
ON t1.join_key = t2.join_key
) joined
WHERE join_key = 1;
然后它告诉我join_key
是无效的标识符。同上t1.join_key
,test_tab1.join_key
,"t1.JOIN_KEY"
,"T1.JOIN_KEY"
和"TEST_TAB1.JOIN_KEY"
。如何识别这些星级选定的列?
答案 0 :(得分:1)
您不需要使用别名,但您需要更明确地在派生表中命名列。例如......
SELECT *
FROM (
SELECT t1.join_key, t1.tab1_uqcol, t2.tab2_uqcol
FROM test_tab1 t1
INNER JOIN test_tab2 t2
ON t1.join_key = t2.join_key
) joined
WHERE join_key = 1;
由于您正在使用内部联接,因此无需区分两个不同的join_key列。您只需在内部查询中列出其中一个,以便外部查询不会混淆。
答案 1 :(得分:1)
您的查询无效SQL。子查询中指定的列必须是唯一的,*只是所有列的语法糖。即使你说的那个也很容易'无效。
看来我错了。 Oracle似乎不遵循ANSI SQL并允许子查询,这可能会产生不明确的列集。事实上,SQLFiddle需要在DML端完成插入,因此它提供了误报。
<强> SQL Fiddle 强>
架构设置(Oracle 11g R2)
CREATE TABLE test_tab1 (join_key NUMBER, tab1_uqcol VARCHAR2(30));
CREATE TABLE test_tab2 (join_key NUMBER, tab2_uqcol VARCHAR2(30));
查询1 :
INSERT INTO test_tab1 VALUES (1, 'table 1 only');
INSERT INTO test_tab2 VALUES (1, 'table 2 only');
SELECT *
FROM (
SELECT *
FROM test_tab1 t1
INNER JOIN test_tab2 t2
ON t1.join_key = t2.join_key
) joined
<强> Results 强>:
ORA-00900: invalid SQL statement
有三种方法可以修改您的查询以解决此问题:
这三个都有不同的缺点,因此取决于您需要如何使用此查询。第二个保证为所有可能的表生成可引用的列集。第三种方法可能稍微容易一些,但如果两个表共享除连接列以外的列的相同列名,则可能会失败。
编辑:我的立场得到了纠正。你是对的。 Oracle确实允许您引用子查询中的重复列。即使Oracle允许你这样做,我仍然会避免它,因为它是不好的做法。它也不会在大多数RDMS中生成有效的SQL。
我将保留答案,因为除非有人发现未记录的方式从外部查询中引用重复的列名,否则您可能别无选择,只能修改内部查询。