PostgreSql 查詢使用

[WITH with_queries] SELECT select_list FROM table_expression [sort_specification]

一、select_list
        a、「*」 :遍歷全部行和用戶定義的全部列從表中。select_list也可使用可用列的子集或列的計算,如:sql

                       select a,  b+c from table1.
        b、使用select命令忽略table_expression,將其當作計算器,如:select 3*4;
        c、select_list中返回不一樣的結果,你能夠調用一個函數,如:select random();數據庫

二、table_expression

    table_expression包含from從句,後面可跟where,group by,having從句,簡單的table_expression引用磁盤上的表,但複雜的table_expression能夠以不一樣的方式修改or結合基表。
    可選where,group by,having從句指定逐次轉換管道執行在from子句派生表中。全部的轉換產生一個虛表,提供經過select_list 計算查詢輸出的行

    a、from 從句
        從給定的一個逗號分隔的表引用列表派生一個or多個其餘表,語法:
        from table_reference [, table_reference [, …]]
        table_reference能夠是一個表的名稱、派生表如子查詢、錶鏈接or這些複雜的組合。若是超過一個table_reference在from從句中列出,它們交叉鏈接造成中間虛表,而後經過where,group by,having從句轉換,造成最後的整個表的表達式。

        錶鏈接
            一個錶鏈接是來自其餘2個表(實表or派生表)根據特定鏈接類型的規則。    

        cross join    
            T1 cross join T2
            從T1和T2中行進行每個可能的組合,如笛卡爾積。T1中有n行,T2中有m行,那麼交叉鏈接後,鏈接表有n*m行。
            From T1 cross join T2 等效於 from T1, T2
            也等效於:from T1 inner join     T2 on true
        
        限制鏈接
        T1 {[inner]|{left|right|full}[outer]} join T2 on boolean_expression
        
        T1 {[inner]|{left|right|full}[outer]} join T2 using(join column list)

        T1 natural {[inner]|{left|right|full}[outer]} join T2
        inner 和 outer 在全部鏈接中是可選的,默認爲inner;left,right,full屬於outer。
        鏈接條件經過on 或 using從句or 經過關鍵字natural指定,鏈接條件決定了哪些行從2個源表匹配,詳細以下:
    
        on從句最廣泛的一個鏈接條件:相似於where從句中的布爾表達式,若on從句爲true時,T1和T2匹配一對行。

        using是一個速記符號:它以逗號分隔列名稱的列表,鏈接表必須有相同的列,造成一個鏈接條件所指定的每個列是相等。因此,using(a,b,c) 等效於 on(t1.a=t2.a and t1.b=t2.b and t1.c=t2.c)

        natural是using的一個速記:使用using列表包含在輸入表中全部列的名稱,如沒有共同列,natural的行爲相似於交叉鏈接

        inner join
            在T1中每行R1,在T2中的每一行知足鏈接條件R1的行

        left outer join
            首先,執行inner join,而後,爲T1中不知足鏈接條件T2中任何行,鏈接行在T2中的列使用null值被添加,因此,鏈接表中至少有1行對應T1中的行。
        right outer join
            首先,執行inner join,而後,爲T2中不知足鏈接條件T1中任何行,鏈接行在T1中的列使用null值被添加,因此,鏈接表中至少有1行對應T2中的行。

        full outer join
            首先,執行inner join,而後, 爲T1中不知足鏈接條件T2中任何行,鏈接行在T2中的列使用null值被添加; 爲T2中不知足鏈接條件T1中任何行,鏈接行在T1中的列使用null值被添加。
    
        t1表
        num | name  
        -----+------
           1 | a
           2 | b
           3 | c
        (3 rows)     
        
        t2表
        num | value  
        -----+-------
         1 | xxx
        3 | yyy
        5 | zzz
        (3 rows)     

        select * from t1 cross join t2;
        select * from t1 inner join t2 on t1.num=t2.num;
         select * from t1 inner join t2 using(num);
        select * from t1 natural inner join t2;
        select * from t1 left join t2 on t1.num=t2.num;
        select * from t1 left join t2 using(num);
        select * from t1 right join t2 on t1.num=t2.num;
        select * from t1 right join t2 using(num);
        select * from t1 full join t2 on t1.num=t2.num;
        select * from t1 full join t2 using(num);

        on從句也可以包含條件,但涉及直接錶鏈接,可能對一些查詢是有用:
        select * from t1 left join t2 on t1.num=t2.num and t2.value='xxx';

        注意:添加where從句將獲得不一樣的結果
        select * from t1 left join t2 on t1.num=t2.num where t2.value='xxx';
        由於在錶鏈接前的on從句已經被處理,而錶鏈接以後where從句被處理。

        表和列的別名
            能夠給表取一個臨時的名字,在查詢的其他部分引用,建立表的別名:
            from table_reference as alias;
            或
            from table_reference alias;
            一般,對錶名稱較長設置別名,可保持join從句可讀性
            設置別名是當前查詢引用表的新名稱,在該查詢中不容許再使用原名稱
            當join從句輸出結果使用別名,該別名隱藏了join從句內的原名稱

        子查詢
            指定一個派生表必須包括在括號中,必須指定表的別名,如:
            from(select * from table1) as alias_name
            當子查詢中涉及分組or彙集時,它不能下降到一個普通的錶鏈接

            子查詢也能表示值列表
            from (values('anne', 'smith'), ('bob','jone')) as names(first, last);
            爲值列表的列指定別名也是可選的

        表函數
            產生行集的函數,由基本數據類型和組合數據類型組成。在查詢的from從句中,它們使用像一張表,視圖or子查詢。經過表函數返回的列能夠包含在select、join或where從句中以相同的方式做爲一個表,視圖or子查詢的列。
            若是一個表函數返回一個基本數據類型,單結果列名匹配函數名,若函數返回複合類型,這些列的結果獲得一個該類型個體屬性。

    b、where從句
        where search_condition
        search_condition返回boolean類型的值
        在from從句處理完成後,從派生虛表中的每一行檢查search_condition,如檢查結果爲true,那麼該行被保持在輸出表中,不然(false/null)它將被丟棄。search_condition一般引用from從句中生成表中的至少一列,這不是必需,但不然,where從句沒有意義。

    c、group by從句和having 從句
        經過where從句過濾後,可能從派生的輸入表進行分組,使用group by從句,使用having從句消除組行。
        select  select_list from … [where …]
        group by grouping_column_reference [, grouping_column_reference]...

        將表中全部列中有相同值的列組合在一塊兒,消除冗餘的輸出or彙集計算。如:
        表test1
         x | y  
         ---+---
          a | 3
          c | 2
           b | 5
           a | 1
         (4 rows)

        select x from test1 group by x;
        這裏不能執行:select * from test1 group by x ,由於表中y列沒有單一的值與每個組相關,分組的列能夠引用select_list中的列由於它們在每一組中有單一值。
        一般,若一個表被分組,沒有列在group by從句中的列不能被引用除了在聚合表達式中的列,如:select x, sum(y) from test1 group by x;
        在嚴格的sql中,group by從句後列僅僅指源表中的列,但pg擴展,容許group by從句後的列是select_list中的列,分組表達式取代簡單列名也被支持。

        若一張表已經使用group by進行分組,但只對一些組感興趣,可使用having從句過濾,相似與where從句,但只從分組的結果中過濾。語法:
        select  select_list from … [where …] group by …
        having boolean_expression
        boolean_expression能夠引用分組表達式和未分組的表達式(在一個聚合函數中的)
        
        eg:
            select x, sum(y) from test1 group by x having sum(y) > 3;
            select x, sum(y) from test1 group by x having x < 'c';express


三、select lists
 table_expression能夠經過組合表、視圖、分組等構建一箇中間虛表,該表最終由select_list處理,select_list來肯定中間表中的哪些列被輸出。
 
 select_list items
 最簡單的一種select_list是*,輸出由table_expression產生的全部列,不然,select_list是一個逗號分隔的值表達式or列的名字,列的名字能夠是表中真實列名字or別名。如有多於1張表有相同的列名,那麼必須給定其表的名稱,如:
 Select tb1.a, tb2.a from …
 若是在select_list增長任意的值表達式,那麼再返回表中增長一個新的虛擬列,值表達式對返回結果的每一行求值一次。服務器

 column labels
 select_list中的項能夠爲後續處理指定一個名稱,該名稱可用於如order by從句or客戶端的應用程序,如:
 select a as value, b+c as sum from … 
 若沒有使用as指定列名,系統默認引用列名。函數調用,則使用函數名。複雜表達式,系統將生成一個通用的名稱。as爲可選,爲避免列名與pg中的關鍵字衝突,可使用雙引號,如:
 Select a value, b+c as sum from … //value 爲pg中關鍵字
 Select a 「value」, b+c as sum from …dom

 distinct
 select_list處理後,結果表能夠經過distinct來消除重複行,如:
 select distinct select_list from …
 用all取代distinct可保持全部行的默認行爲。若是2行中至少一列值不一樣,則2行認爲是不一樣的,null值在比較是相同的。另外,一個任意表達能夠肯定哪些行是不一樣的,語法:
 Select distinct on (expression [, expression …]) select_list …
 expression:評估全部行的任意值表達式,一個行集的全部表達式相等被視爲重複,只有行集中的第一個保留到輸出中。注意,行集的第一行是不可預知的,除非足夠列的查詢是排序,保證惟一的行排序在distinct處理前(distinct處理髮生在order by以後)
 distinct on從句不是sql標準,有時被認爲很差的風格,由於處理結果的不肯定性,較好的作法:在from從句中使用group by和子查詢。函數

四、combining queries
 2個查詢結果可使用union、intersection、difference操做符進行結合,語法:
 query1 union [all] query2
 query1 intersect [all] query2
 query1 except [all] query2
 set operations能夠被嵌套or組成鏈,如:
 query1 union query2 union query3
 union:添加query2的結果到query1中,雖然沒有保證行真實返回的順序。從它的結果中消除了重複行,相似於distinct;若使用union all不會消除重複行。
 intersect:包含query1和query2中的全部行,重複行會消除除非all使用
 except:返回在query1中不在query2中的全部行,重複行會消除除非all使用。
 爲了計算2個查詢結果的union、intersection、difference,這2個query必須兼容,即他們返回相同的列數和相應的列具備兼容的數據類型。優化

五、Sorting Rows
    通過查詢產生的輸出列表(在select list處理以後)能夠排序,如不指定行的排序,將返回一個不肯定的行順序,實際的順序依賴於掃描和鏈接計劃類型以及磁盤上的順序,但這個是不能依靠,只有明確指定排序才能返回一個特定的輸出順序。
    
    order by從句指定排序:

        select select_list from table_expression
            order by sort_expression [ASC|DESC] [NULLS {FIRST|LAST}]
            [, sort_expression2 [ASC|DESC] [NULLS {FIRST|LAST}] …]

     sort_expression(s)能夠是select_list中任何有效的表達式:
        select a,b from table1 order by a+b, c;
    當指定排序表達式多個時,後面的排序表達式行排序是根據其前面的排序表達式的值進行比較。每一個表達式後面可跟ASC 或DESC關鍵字來指定行的順序是升序or降序,默認爲ASC。
    NULLS FIRST 或NULLS LAST 是用來肯定nulls出如今 non-nulls以前或以後。默認null值排序大於任何non-null值,所以, NULLS FIRST是DESC的默認方式。
    注意,排序選項是獨立的排序列,order by x,y DESC 等於 order by x ASC,y DESC

    一個 sort_expression能夠是列標籤名 or 輸出列數,如根據輸出的第一列排序:
    select a+b as sum, c from table1 order by sum;
    select a, max(b) from table1 group by a order by 1;

    注意,輸出列是單獨的列,以下面錯誤方式:
    select a+b as sum, c from table1 order by sum + c;
    這個限制減小了混亂,若是排序項名稱既匹配輸出列名字或表中列的名字時仍然存在混亂。

    
六、limit and offset
    limit and offset容許你檢索一部分的行集,語法:
    select select_list from table_expression
        [order by …]
        [limit {number|ALL}] [offset number]
    若是指定limit count,不會有更多的行返回(但可能少於count,若是查詢自己行小於count)。Limit ALL等同於與忽略limit從句。
    offset跳過多少行開始檢索返回行。Offset 0 至關於忽略offset從句。

    當使用Limit時,使用order by 從句約束結果行集到一個惟一的序列很是重要。不然,你獲得一個不可預知的子集,你可能會問第十行至第二十行,但第十行至第二十行是什麼樣的順序?此順序未知,除非你明確指定order by

    查詢優化以使用limit到帳戶當生成查詢計劃時,因此你頗有可能根據的給的limit 和 offset獲取不一樣的查詢計劃。所以,使用limit/offset值來選擇查詢結果的不一樣子集。

    因爲offset從句是在服務器端計算,所以一個大的offset多是低效的。


七、values lists
    values提供一個生成常量表的方式,它可使用在一個沒有真實建立和操做磁盤上表的查詢上,語法:
    values (expression [, ...]) [, …]
    每一個括號內的列表生成表裏的一行,列表必須有相同的元素數量(至關於表相同數量列)而且,每一個列表中相應的元素具備兼容的數據類型。結果列的實際類型由相同規則決定經過union,如:

    VALUES (1, 'one'), (2, 'two'), (3, 'three');
    等效於
    SELECT 1 AS column1, 'one' AS column2
    UNION ALL
    SELECT 2, 'two' UNION ALL SELECT 3, 'three';


    默認,pg指定column1,column2,等爲值表的列。這個column name不是sql標準而且不一樣的數據庫系統可能不一致,故,最好的作法使用表的別名重寫默認方法的名字,如:
    
    select * from (values (1,'one'),(2,'two'),(3,'three')) as t(num, letter);

排序

相關文章
相關標籤/搜索