2017-03-20 80 views
1

以下是来自PostgreSQL documentationSELECT的简介。在我看来,有时我们写<expression> AS <name>,有时候是<name> AS <expression>。在普通的英语,我倾向于认为<expression> AS <name>是更常见(如“地址她。史密斯博士,谢谢。,而我无法理解如何看待<name> AS <expression>'AS'在SQL中的含义是什么?

  1. 我们如何能区别在哪里使用<name> AS <expression><expression> as <name>区别?
  2. 什么是每一个?
  3. 最小明显的例子是有各种普通的语言,这将使它非常直观何时使用什么相似之处?
[ WITH [ RECURSIVE ] with_query [, ...] ] 
SELECT [ ALL | DISTINCT [ ON (expression [, ...]) ] ] 
    * | expression [ [ AS ] output_name ] [, ...] 
    [ FROM from_item [, ...] ] 
    [ WHERE condition ] 
    [ GROUP BY expression [, ...] ] 
    [ HAVING condition [, ...] ] 
    [ WINDOW window_name AS (window_definition) [, ...] ] 
    [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ] 
    [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] 
    [ LIMIT { count | ALL } ] 
    [ OFFSET start [ ROW | ROWS ] ] 
    [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] 
    [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ] 
where from_item can be one of: 

    [ ONLY ] table_name [ * ] [ [ AS ] alias [ (column_alias [, ...]) ] ] 
    (select) [ AS ] alias [ (column_alias [, ...]) ] 
    with_query_name [ [ AS ] alias [ (column_alias [, ...]) ] ] 
    function_name ([ argument [, ...] ]) [ AS ] alias [ (column_alias [, ...] | column_definition [, ...]) ] 
    function_name ([ argument [, ...] ]) AS (column_definition [, ...]) 
    from_item [ NATURAL ] join_type from_item [ ON join_condition | USING (join_column [, ...]) ] 
and with_query is: 

    with_query_name [ (column_name [, ...]) ] AS (select | values | insert | update | delete) 

TABLE [ ONLY ] table_name [ * ] 
+0

公共表格表达式的“as”在例如相同的情况下是相同的。 'create view foo AS select ...'或者在'create table xy AS select ...'中。名称和别名的重载用法由SQL标准定义,它不是Postgres发明的。 –

回答

2

我喜欢这个问题。

这里是我看到它,我如何向人们解释,希望它有助于:

让我们先从<expression> as <name>。现实生活中最简单的类比是缩写。它是为了使代码更清晰,更易于阅读和简化而创建的。我们假设一个场景:我们有来自麻省理工学院的所有学生的数据以及马萨诸塞州汽车部在我们的数据库中,我们想要找到有加快车票和他们已经支付的学生。

SELECT 
    government.SocialSecurityAdministration.FirstName, 
    government.SocialSecurityAdministration.LastName, 
    education.MasachusettsInstituteOfTechnology.Faculty 
    government.DepartmentOfMotorVehiclesTickets.TicketTotal, 
    government.SocialSecurityAdministration.SocialSecurityNumber 
FROM 
    education.MasachusettsInstituteOfTechnology 
    INNER JOIN government.DepartmentOfMotorVehiclesTickets ON education.MasachusettsInstituteOfTechnology.SocialSecurityNumber = government.DepartmentOfMotorVehicles.SocialSecurityNumber 
    INNER JOIN government.SocialSecurityAdministration ON government.DepartmentOfMotorVehicles.SocialSecurityNumber = government.SocialSecurityAdministration.SocialSecurityNumber 

长相丑陋,不是吗?在现实生活中,我们略科技的麻省理工学院是MIT和机动车辆部门要DMV。我不知道社会安全管理局的官方缩写(但我们可以拿出一个),但我们说SSN当我们的意思是社会安全号码。让我们来实现这个想法:

SELECT 
     ssnAdm.FirstName, 
     ssnAdm.LastName, 
     ssnAdm.Faculty 
     dmv.TicketTotal, 
     ssnAdm.SocialSecurityNumber AS ssn 
    FROM 
     education.MasachusettsInstituteOfTechnology AS mit 
     INNER JOIN government.DepartmentOfMotorVehiclesTickets AS dmv ON mit.SocialSecurityNumber = dmv.SocialSecurityNumber 
     INNER JOIN government.SocialSecurityAdministration AS ssAdm ON dmv.SocialSecurityNumber = dmv.SocialSecurityNumber 

现在看起来好多了,不是吗?

现在到它的<name> as <expression>部分。这样做是为了简化代码以及一些性能优化,但现在让我们专注于简化。使用上面使用过的相同示例,您可能想要/询问以下内容:“对于每位获得票证的麻省理工学院学生,我需要了解其SSN的最后4位数字,他们的姓氏,他们的银行账户中的钱和他们最近的VISA交易金额“。 是的,你在CIA工作。

让我们把它写:

SELECT 
    RIGHT(4,ts.ssn) as LastFourDigitsSsn, 
    ts.LastName, 
    bad.TotalAmount, 
    ISNULL(visa.TransactionAmt,'Student uses MasterCard') AS VisaTransaction 
FROM 
    (SELECT 
     ssnAdm.FirstName, 
     ssnAdm.LastName, 
     ssnAdm.Faculty 
     dmv.TicketTotal, 
     ssnAdm.SocialSecurityNumber AS ssn 
    FROM 
     education.MasachusettsInstituteOfTechnology AS mit 
     INNER JOIN government.DepartmentOfMotorVehiclesTickets AS dmv ON mit.SocialSecurityNumber = dmv.SocialSecurityNumber 
     INNER JOIN government.SocialSecurityAdministration AS ssAdm ON dmv.SocialSecurityNumber = dmv.SocialSecurityNumber 
    ) AS ts 
    INNER JOIN business.BankAccountsData AS bad ON ts.ssn = bad.SocialSecurityNumber 
    OUTER APPLY (SELECT TOP 1 TransactionAmt FROM business.VisaProcessingData vpd WHERE vpd.BankAccountID = bad.ID ORDER BY TransactionDateTime DESC) as visa 

好,相貌丑陋一次。但是如果我们简化一下并在实际陈述之外表达某些事情呢?那时<name> as <expression>进来。让我们这样做:

WITH MitTicketedStudents AS (
    SELECT 
     ssnAdm.LastName, 
     ssnAdm.SocialSecurityNumber as ssn, 
     RIGHT(4,ssnAdm.SocialSecurityNumber) as LastFourDigitsSsn 
    FROM 
     education.MasachusettsInstituteOfTechnology AS mit 
     INNER JOIN government.DepartmentOfMotorVehiclesTickets AS dmv ON mit.SocialSecurityNumber = dmv.SocialSecurityNumber 
     INNER JOIN government.SocialSecurityAdministration AS ssAdm ON dmv.SocialSecurityNumber = dmv.SocialSecurityNumber 
), 
LatestVisaTransactions AS (
    SELECT DISTINCT 
     BankAccountID, 
     FIRST_VALUE(TransactionAmt) OVER (PARTITION BY BankAccountId ORDER BY TransactionDateTime DESC) as TransactionAmt 
    FROM 
     business.VisaProcessingData 
) 

-- And let's use our expressions now 

SELECT 
    mts.LastFourDigitsSsn, 
    mts.LastName, 
    bad.TotalAmount, 
    ISNULL(lvt.TransactionAmt,'Student uses MasterCard') AS VisaTransaction 
FROM 
    MitTicketedStudents mts 
    INNER JOIN business.BankAccountsData AS bad ON mts.ssn = bad.SocialSecurityNumber 
    LEFT OUTER JOIN LatestVisaTransactions lvt ON bad.ID = lvt.BankAccountID; 

看起来更好,不是吗?

结论:当你想分离代码时,你使用<name> as <expression>,当你想给某个别名来简化代码时,你使用<expression> as <name>

+0

请注意,SQL或Postgres中没有'OUTER APPLY'。 SQL标准(和Postgres)中的等价物将是一个“横向”外连接。 –

+0

@a_horse_with_no_name我很感激编辑,我正在用T-SQL编写......这个问题已经足够普遍,答案适用于两者,但是如果您可以更新语法来匹配问题的标签,那将会很棒。谢谢! –

+0

' as '与英文中那种形式的某些结构是否一致? – Hatshepsut

1

重要的是它出现的地方。

mytable: 
mycolumn myothercolumn 
---------------------- 
     1    a 
     2    b 

SELECT myrow.mycolumn * 2 AS mylabel 
FROM (SELECT * FROM mytable) AS myrow 
WHERE myrow.mycolumn > 1 

mylabel 
------- 
     4 

在SELECT中,我们引用表达式的值作为某个输出列名(“列别名”)的值。在FROM中,我们引用表格表达式的某个名称(“表别名”,“相关名称”)的值(典型行)。

(事实证明,语法拼写错误的,因为细节问题较少,如果我们在SELECT子句AS使用,但不FROM子句为正在使用。)

有AS的其他用途。上下文还决定了它们的含义,并且它们也对应于使用名称来引用某些内容。

在技术环境中,试图根据技术术语的日常意义来理解什么是意义的,包括理解基于其名称的事物是什么。 SQL语言设计人员[原文如此]并没有选择总是有<expression> AS <name><name> AS <expression>。那就是这样。这就是你如何写东西来让你的程序去做东西。 (接受但更现代的计算机语言设计原则确实提出了更多的常规符号。)

+0

似乎这两个例子都是' AS ',但是在定义一个[function](https://www.postgresql.org/docs/9.1/static/sql-createfunction.html)(例如)时使用'作为'。是对的吗?有什么不同? – Hatshepsut

+0

看到我添加的最后一段。法式烤面包不是烤面包。我们应付。语境。 – philipxy