我正在优化可读性。在适用的情况下,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) |