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);

排序

相关文章
相关标签/搜索