Oracle 联接使用 + 派生列

  • 本文关键字:派生 Oracle sql oracle
  • 更新时间 :
  • 英文 :


我正在优化可读性。在适用的情况下,SQL 联接"using"语法在语法上不如"on"那么详细。理想情况下,我想写:

select *, 
col1 + col2 as derviedCol 
from table1 join table2 using (joinCol1, joinCol2)

但是 oracle(我怀疑其他数据库(在使用"using"语法 (ORA-00904( 时不会让您使用表标识符,所以我能做的下一件最好的事情是:

select t.*, 
col1 + col2 as derviedCol 
from (
select * from table1 join table2 using (joinCol1, joinCol2)
) t

select t1.*, t2.*, 
col1 + col2 as derviedCol 
from table1 t1 
join table2 t2 on 
t1.joinCol1 = t2.joinCol1 
and t1.joinCol2 = t2.joinCol2

有人可以建议更简洁的语法吗?

您可以分配别名并使用别名来限定列计算;例如

select co.shortname || '.' || ci.shortname as mycol
from countries co
join cities ci using (ISOCODE);

或者只是通过列各自的表名限定列;例如

select countries.shortname || '.' || cities.shortname as mycol
from countries
join cities using (ISOCODE);

不确定这是否符合您对"不那么冗长"的定义

我挑战开场白,并认为"使用语法"不那么"干净"。即使有通用名称要联接,并且自然联接"隐藏"了"重复的列名",派生表仍然可以包含同名的列(例如,下面看到的"shortname"存在于两者中,但不是联接的一部分(。

此外,如果"using join"指定了两列,则返回两列,即使它们具有相同的列名也是如此。

对于联接语法中的几个额外字符,您将获得一种更精确(和灵活(的方法,该方法可用于任何查询,而无需特殊的数据模型条件。我还认为,使用 ON 样式连接的语法一致性导致可变性较小,因此更容易维护。

SQL 小提琴

Oracle 11g R2 架构设置

CREATE TABLE COUNTRIES
(COUNTRY varchar2(9), ISOCODE varchar2(3), SHORTNAME varchar2(4))
;
INSERT ALL 
INTO COUNTRIES (COUNTRY, ISOCODE, SHORTNAME)
VALUES ('Aruba', 'ABW', NULL)
INTO COUNTRIES (COUNTRY, ISOCODE, SHORTNAME)
VALUES ('Australia', 'AUS', 'Oz')
INTO COUNTRIES (COUNTRY, ISOCODE, SHORTNAME)
VALUES ('Austria', 'AUT', NULL)
SELECT * FROM dual
;
CREATE TABLE CITIES
(ISOCODE varchar2(3), CITY varchar2(9), SHORTNAME varchar2(3))
;
INSERT ALL 
INTO CITIES (ISOCODE, CITY, SHORTNAME)
VALUES ('AUS', 'Melbourne', 'Mel')
SELECT * FROM dual
;

查询 1

select * from countries join cities using (ISOCODE)

结果

| ISOCODE |   COUNTRY | SHORTNAME |      CITY | SHORTNAME |
|---------|-----------|-----------|-----------|-----------|
|     AUS | Australia |        Oz | Melbourne |       Mel |

查询 2

select * from countries join cities using (ISOCODE,ISOCODE)

结果

| ISOCODE | ISOCODE |   COUNTRY | SHORTNAME |      CITY | SHORTNAME |
|---------|---------|-----------|-----------|-----------|-----------|
|     AUS |     AUS | Australia |        Oz | Melbourne |       Mel |

查询 3

select * from countries left join cities using (ISOCODE)

结果

| ISOCODE |   COUNTRY | SHORTNAME |      CITY | SHORTNAME |
|---------|-----------|-----------|-----------|-----------|
|     AUS | Australia |        Oz | Melbourne |       Mel |
|     AUT |   Austria |    (null) |    (null) |    (null) |
|     ABW |     Aruba |    (null) |    (null) |    (null) |

查询 4

select * from countries left join cities using (ISOCODE,ISOCODE)

结果

| ISOCODE | ISOCODE |   COUNTRY | SHORTNAME |      CITY | SHORTNAME |
|---------|---------|-----------|-----------|-----------|-----------|
|     AUS |     AUS | Australia |        Oz | Melbourne |       Mel |
|     AUT |     AUT |   Austria |    (null) |    (null) |    (null) |
|     ABW |     ABW |     Aruba |    (null) |    (null) |    (null) |

最新更新