2017-03-20 81 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