SQL表格/子查询别名规范

3
多年来,我一直在各种DBMS(如Oracle、SQL Server、MySQL、Access等)上编写SQL,其中一个问题总是让我感到困惑,那就是似乎缺乏针对表格和子查询别名的命名约定。
我经常听说使用表格别名是正确的做法,尽管我并不总是使用它们,但当我使用时,我总是为使用什么名称而犯愁。我曾经使用过描述性的名称,也用过单个字符,例如“t”、“s”或“q”,然后又改回去了。例如,我刚刚写的这个MS Access查询,即使是这样相对简单的查询,我仍然不满意我使用的别名,我仍然认为它不太容易阅读。
SELECT stkTrans.StockName
    , stkTrans.Sedol
    , stkTrans.BookCode
    , SUM(IIF(stkTrans.TransactionType="S", -1 * stkTrans.Units, 0)) AS [Sell Shares]
    , SUM(IIF(stkTrans.TransactionType="B", stkTrans.Units, 0)) AS [Buy Shares]
    , SUM(IIF(stkTrans.TransactionType="B", -1 * stkTrans.Price, 0) * stkTrans1.Min_Units) + SUM(IIF(stkTrans.TransactionType="S", stkTrans.Price, 0) * stkTrans1.Min_Units) AS [PnL]
    , "" AS [Comment]
FROM tblStockTransactions AS stkTrans 
INNER JOIN (SELECT sT1.BookCode
                    , sT1.Sedol
                    , MIN(sT1.Units) AS [Min_Units]
            FROM tblStockTransactions sT1
            GROUP BY sT1.BookCode, sT1.Sedol
            HAVING (SUM(IIF(sT1.TransactionType="S", 1, 0)) > 0
            AND SUM(IIF(sT1.TransactionType="B", 1, 0)) > 0)) AS stkTrans1 ON (stkTrans.BookCode = stkTrans1.BookCode) AND (stkTrans.Sedol = stkTrans1.Sedol)
GROUP BY stkTrans.BookCode, stkTrans.StockName, stkTrans.Sedol;

你认为怎么样?我觉得抛出这个问题,看看其他人对此的感受。
3个回答

3

我不知道有关于在数据库中为表/查询起别名的正式规则,但是我了解到Oracle建议使用缩写词,并且长度应该为三至四个字符。

通常情况下,我会避免使用单个字母的缩写,除非查询足够简单,以至于这些缩写对于任何需要维护代码的人来说都是完全清晰的-通常每个查询不超过两到三个表。

我也通常避免使用符合你的数据库表命名约定的长别名,因为这会导致不清楚哪个是数据库表名,哪个是别名。

在提供的示例中,内联视图中的别名sT1是完全没有必要的,因为在内联视图中只有一个表被访问。这样,在查询中只有一个表与一个基于相同表的内联视图进行连接-在这种情况下,我将使用 s 作为表的别名,使用 s1 作为内联视图的别名(以表明它正在查询相同的底层数据库表)。


1
内联视图中的别名sT1是完全不必要的。据我所知,这样做是为了帮助未来的开发,例如当(而不是如果)需要将第二个表添加到查询中时,关联名称已经存在,更改在源代码控制比较中看起来不那么侵入等等。 当然,YAGNI(你不会需要它)但这就是这种想法的理由 ;) - onedaywhen
这正是我的观点。有时我会为内联视图添加别名,比如ST1,但并不总是这样做。恰好在我目前工作的地方,我们总是规定必须为所有东西都使用别名! - markblandford
@onedaywhen 未来的开发可能永远不会发生,但是你将永远受到额外开销的困扰。如果未来有开发需求,那么开发者有责任修改别名以最适合当前情况。 - NeverEndingQueue
@NeverEndingQueue:我改变了我的看法,我现在同意你。我仍然认为它更容易解析(无论是机器还是人类),但即使在这个例子中也没有多大价值。 - onedaywhen

0
如果我使用SQL Server,我可能会将派生表放在公共表达式(CTE)中,并赋予一个逻辑名称(以指示该表的内容),然后在主查询中使用相关名称(“表别名”)进行缩短(以提高可读性),例如:
WITH StockTransactions__type_S_or_B__smallest_units
     AS
     (
      <derived table query here>
     )
SELECT stkTrans.StockName
       ...
FROM tblStockTransactions AS stkTrans 
INNER JOIN StockTransactions__type_S_or_B__smallest_units AS stkTrans1 
   ON (stkTrans.BookCode = stkTrans1.BookCode) AND (stkTrans.Sedol = stkTrans1.Sedol)
GROUP BY stkTrans.BookCode, stkTrans.StockName, stkTrans.Sedol;

显然,在Access中这不是一个选项,所以你直接使用相关名称并完全失去了全名。虽然这不是理想的,但在我看来还是可以接受的。


SQL要求为派生表分配一个名称,但实际上并没有任何理由。这个例子来自Hugh Darwen,我们可以安全地假设这个义务让他感到烦恼:

SELECT DISTINCT E#, TOTAL_PAY 
FROM ( SELECT E#, SALARY + BONUS AS TOTAL_PAY
FROM EMP ) AS TEETH_GNASHER
WHERE TOTAL_PAY >= 500

就这样一个毫无意义的要求,我个人选择了一个几乎没有意义和争议的名称,DT1,它是“第一个派生表”的缩写,允许使用DT2、DT3等等。

SELECT DISTINCT E#, TOTAL_PAY 
FROM ( SELECT E#, SALARY + BONUS AS TOTAL_PAY
FROM EMP ) AS DT1
WHERE TOTAL_PAY >= 500

完全同意使用派生表。幸运的是,我不必面对太多的MS Access开发。 - markblandford

0

DT1和DT2似乎是一个不错的方法.. 我现在正处于理解现有程序阶段,一些程序使用了这种命名约定DT1、DT2.. 这样理解起来相当简单..而不是给表取一个缩写作为别名


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接