《SQL与关系数据库理论——如何编写健壮的SQL代码》一3.9 SQL中的列命名

简介: 本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第3章 ,第3.9节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第3章 ,第3.9节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.9 SQL中的列命名

在关系模型中:(a)所有关系的所有属性都有名称(即不允许有匿名属性);(b)在相关的关系中属性名称都是唯一的(即不允许有重复属性名)。在SQL中,有时会执行类似的规则,但并不总是执行。具体说,规则在表恰好是通过CREATE TABLE和CREATE VIEW定义的表变量的当前值时被执行,但是对于表是某些表达式的返回结果的情况则不执行。注10强烈建议:只要有必要(且可能),就要使用AS子句给列取恰当的列名,否则就会根本没有名字或者会有不唯一的名字。下面是些示例:

SELECT DISTINCT SNAME , 'Supplier' AS TAG 
FROM   S

SELECT DISTINCT SNAME , 2 * STATUS AS DOUBLE_STATUS 
FROM   S

SELECT MAX ( WEIGHT ) AS MBW 
FROM   P
WHERE  COLOR = 'Blue'

CREATE VIEW SDS AS
     ( SELECT DISTINCT SNAME , 2 * STATUS AS DOUBLE_STATUS
       FROM   S ) ;

SELECT DISTINCT S.CITY AS SCITY , P.CITY AS PCITY 
FROM   S , SP , P
WHERE  S.SNO = SP.SNO 
AND    SP.PNO = P.PNO

SELECT TEMP.*
FROM ( SELECT * FROM S JOIN P ON S.CITY > P.CITY ) AS TEMP
     ( SNO , SNAME , STATUS , SCITY ,
       PNO , PNAME , COLOR , WEIGHT , PCITY )

当然,如果不用引用匿名列或非唯一命名列,前面的建议也可以忽略。比如,第3个示例在某些场合(可能在WHERE或HAVING子句中)可以安全缩写为:

SELECT MAX ( WEIGHT ) 
FROM   P
WHERE  COLOR = 'Blue'

更重要的是,这个建议在用VALUES表达式指定表时根本不使用。然而,这是可以变通的。比如下面的示例就是合法的。

SELECT TEMP.*
FROM ( VALUES ( 'S1' , 'Smith' , 20 , 'London' ) ,
              ( 'S2' , 'Jones' , 10 , 'Paris'  ) ,
              ( 'S3' , 'Blake' , 30 , 'Paris'  ) ,
              ( 'S4' , 'Clark' , 20 , 'London' ) ,
              ( 'S5' , 'Adams' , 30 , 'Athens' ) )
       AS TEMP ( SNO , SNAME , STATUS , CITY )

解释:我把VALUES表达式套在括号中(也因此使其成为子查询),附加了一个AS子句,并指定了列名以及AS子句中的“相关名称”(参见第12章)。
重要提醒:关系代数的运算符在很多方面依赖于正确的属性命名。比如,(在第6章中会看到)关系UNION运算要求其运算元具有相同的标题(也就是相同的属性名),而结果也具有相同的标题。此种模式的好处之一就是避免了位置依赖所导致的复杂性(在SQL中存在)!因此,为了关系化地使用SQL,应该对那些关系运算在SQL中的类比项也应用相同的规则。强烈建议:作为执行此规则的前置条件,如果SQL中的两列表示“同种类型的信息”,无论如何也要尽可能给它们同一名称(作为例子,这也是为什么suppliers-and-parts数据库示例中两个供应商编号列都叫SNO,而不是在一个表中叫SNO,在另一个表中叫SNR)。相反的,如果两个列代表不同类型的信息,那么给它们不同的名称通常是个好主意。
唯一会导致无法适用前面建议的情况是,两个列在同一个表中,表示同种类型的信息。比如,考虑一个SQL表EMP包含了代表员工编号的列和代表经理编号的列,其中经理编号本身也是员工编号。这两个列必须使用不同的名称,即ENO和MNO。结果是,有时不得不做列重命名,如下例所示(注意在第3行中的声明“ENO AS MNO”):

( SELECT ENO , MNO FROM EMP ) AS TEMP1
  NATURAL JOIN
( SELECT ENO AS MNO , ... FROM EMP ) AS TEMP2
/* “...” 为EMP表中除ENO和MNO之外的列 */

如果原先就没有对列恰当命名,而你又想关系化地使用SQL,那么就必须做此类重命名了(比如,你面对的是别人定义的数据库,这无疑是实践中的常见情况)。此种情况下你可以考虑如下策略:
为数据库中的每个表T定义与表T相同(除了要对某些列的重命名之外)的视图V。
确保所有视图定义都遵循前述列命名规则。
对视图而不是底层的基表进行运算。
不幸的是,要想完全忽略“SQL中的列具有排序位置”这一事实是不可能的。(当然,就是因为这一事实SQL才能处理匿名列和重复列名。)尤其要注意,SQL中的列在不需要排序的时候仍然具有排序位置(即当它们都正确命名的情况);此点特别适用于基表中的列和视图。强烈建议:不要编写依赖于位置的SQL代码。SQL强调要用这种定位的例子包括(但可能不限于):
SELECT *(参见第12章);
FROM子句,在指定多个表时;
显式JOIN运算(参见第6章);
UNION、INTERSECT和EXCEPT运算,在没有指定CORRESPONDING时(参见第6章);
在范围变量定义中指定的列名列表中(参见第12章);
在CREATE VIEW中指定的列名列表(参见第9章);
没有指定列名列表的INSERT(参见第5章);
VALUES表达式;
行赋值和比较;
ALL和ANY比较,在比较元的度大于1时(参见第11章)。

相关文章
|
10天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
74 10
|
10天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
122 6
|
10天前
|
SQL 前端开发
基于jeecgboot复杂sql查询的列表自定义列实现
基于jeecgboot复杂sql查询的列表自定义列实现
14 0
|
10天前
|
SQL Java 数据库
java代码中调用dao层查询接口,代码没有返回数据,打印出的sql查出了数据
java代码中调用dao层查询接口,代码没有返回数据,打印出的sql查出了数据
17 1
|
10天前
|
SQL XML Java
整理几个常用的sql和其他代码
整理几个常用的sql和其他代码
13 1
|
10天前
|
SQL 存储 关系型数据库
【MySQL】——关系数据库标准语言SQL(大纲)
【MySQL】——关系数据库标准语言SQL(大纲)
60 0
【MySQL】——关系数据库标准语言SQL(大纲)
|
SQL 数据库
《SQL与关系数据库理论——如何编写健壮的SQL代码》一3.7 TABLE_DUM和TABLE_DEE
本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第3章 ,第3.7节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1005 0
|
7天前
|
SQL API 流计算
实时计算 Flink版产品使用合集之在Mac M1下的Docker环境中开启SQL Server代理的操作步骤是什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
22 1
|
1天前
|
SQL 存储 搜索推荐
SQL server增删改查(1)
SQL server增删改查(1)
7 0