解释 SQL 语法:Select tbl.*

Explain SQL Syntax: Select tbl.*

我有一个不太明白的问题:

SELECT DISTINCT TBL.*
FROM (
SELECT
     attribute1,
     attribute2,
     etc...
FROM table) TBL

我猜 TBL 正在为结果集命名,但为什么在 select 语句中需要它以及 '.' 的作用是什么?做?

. 表示您正在引用 table TBL(在您的情况下是子查询)的列(或所有列)

外部查询仅将 DISTINCT 应用于内部查询的每一列

请注意,在您的情况下,嵌套查询没有多大意义,您可以像这样重写查询:

SELECT DISTINCT att1, att2, ... FROM table

另请注意,如果您不使用聚合,则您的查询在功能上等同于分组依据:

SELECT att1, att2, ... FROM table GROUP BY att1, att2, ...

在您的示例中,TBL.** 之间没有区别,但假设您的查询类似于

 Select * from Customer 
   Inner Join Country on Country.ID = Customer.CountryID
  where Country.Code = 'UK'

这将 return 客户和国家 table 中的每一列,而

 Select Customer.* from Customer 
   Inner Join Country on Country.ID = Customer.CountryID
  where Country.Code = 'UK'

只会 return 客户中的列 table

也和这个一样:

SELECT DISTINCT TBL.*
FROM (
    SELECT
         attribute1,
         attribute2,
         etc...
    FROM (
        SELECT
            attribute1,
            attribute2,
            etc...
        FROM table
        ) TBL2
    ) TBL

有点傻,不是吗?

TBL 和 TBL2 是仅 "exist" 用于引用查询中的事物的名称。我指出任何时候你在 FROM 子句中提到 table 作为 table TBLn 它基本上等同于说 (SELECT * FROM table) TBLn.

将这些表达式(也称为派生 tables、嵌套视图、内联视图)嵌入到查询中有很多充分的理由,但只有当您查看一个不作为的示例时,它们的实用价值才会变得更加明显和你那里的那个一样毫无意义。

我不知道有哪个平台不需要 TBL 这样的名称。在某些情况下,将其排除在外会很方便。在我的查询中,列引用没有歧义,我什至根本不必提及“TBL2”。从这个意义上说,我根本 "doing" 什么都不是。

在过程语言中,我可以进行一整套无意义的变量赋值(比如 a1 = 42; a2 = a1; a3 = a2; a4 = a3; a5 = a4; ...),编译器可能会意识到大多数变量永远不会被使用,因此它不会费心去浪费内存或 CPU 循环。它基本上承认你与他们 "doing" 没有任何关系。不要将 SQL 视为过程语言,但以类似的方式 SQL 解析器(和优化器)将解析所有这些 temporary/shorthand 名称并找出最佳方法return查询结果。

据我所见,题主还是没看懂。我相信他了解一些 OOP 基础知识。 假设您在 OOP 编程语言中有一些 class 的数组。假设它是这样的:

<classA>Array[] TBL = new classA();

class 类似于:

class classA {
 int   attribute1,
 string    attribute2,
...
}

然后假设您已经在 class 中有了数据,所以数组 TBL 中有一些元素。 如果你想从这个数组中获取一些元素,你正在做类似 TBL[1].getAttribute1, TBL[1].getAttribute2....

因此,在您的问题中,您有一组数据,在 SQL 世界中称为 SUBQUERY,您将其命名为 'TBL'(您可以选择任何您喜欢的名称)。

(
SELECT
     attribute1,
     attribute2,
     etc...
FROM table) TBL

现在您想从此数组中获取元素。通过 SQL 语法,您需要指定您想要获得的确切内容。例如:TBL.attribute1, TBL.attribute2, ... 但是如果你想显示这个数组的所有元素,你只需使用 * 代替。 --> 待定。*

现在让我们回到 SUBQUERY。您可以使用 tables/views/functions 代替它。所有这些都可以用您喜欢的任何名称命名(名称=别名)。稍后您可以使用此别名来更轻松地编写代码。