选择查询

选择查询读取和处理hubble中的数据。它们比简单的SELECT子句更通用:它们可以使用集合操作对一个或多个选择子句进行分组,并且可以请求特定的排序或行限制。

可能会发生选择查询:

  • 在查询的顶层,与其他SQL语句一样。
  • 括号之间作为子查询。
  • 作为将表格数据作为输入的其他语句的操作数,例如INSERTUPSERTCREATE TABLE ASALTER ... SPLIT AT

条款

TABLE条款

语法

TableStmt
TABLEtab_ref

子句从指定的TABLE表中读取表格数据。结果表数据的列以表的模式命名。

TABLE a相当于select * from a

create table tb_copy as table tb;

此语句将表中的内容复制tb到新表中。但是,该TABLE子句不保留从其读取的表的架构中的索引、外键或约束和默认信息。

SELECT条款

有关详细信息,请参阅简单查询子句

设置操作

集合操作结合了来自两个选择子句的数据。它们作为其他集合操作的操作数或作为选择查询中的主要组件是有效的。

语法

SelectStmt
select_clauseUNIONINTERSECTEXCEPTALLDISTINCTselect_clause

集合运算符

SQL允许您比较多个选择子句的结果。您可以将每个集合运算符视为表示布尔运算符:

  • UNION=OR
  • INTERSECT=AND
  • EXCEPT=NOT

默认情况下,这些比较中的每一个仅显示每个值的一个副本(类似于SELECT DISTINCT)。

建表及其数据准备:

create table cust_infobak(
    cust_no       string primary key,
    cust_name     varchar(30) not null,
    cust_card_no  varchar(18),  
    cust_phoneno  decimal(15),
    cust_address  varchar(30),
    cust_type     varchar(10),
    index(cust_card_no)
 );

insert into cust_infobak values('14435551','张贺','431256197306265320',15534343555,'山西临汾','质押');
insert into cust_infobak values('14435552','刘明','371452199303034312',18967756743,'陕西延安','信用');
insert into cust_infobak values('14435553','李华','52112119860621421X',15833355455,'湖北武汉','抵押');
insert into cust_infobak values('14435554','郑青','213456199102275341',13054546567,'江西南昌','质押');
create table cust_info(
    cust_no       string primary key,
    cust_name     varchar(30) not null,
    cust_card_no  varchar(18),  
    cust_phoneno  decimal(15),
    cust_address  varchar(30),
    cust_type     varchar(10),
    index(cust_card_no)
 );
 
 
insert into cust_info values('14435550','王吉','12022519960321531X',15122511874,'天津武清','抵押');
insert into cust_info values('14435551','张贺','431256197306265320',15534343555,'山西临汾','质押');
insert into cust_info values('14435552','刘明','371452199303034312',18967756743,'陕西延安','信用'); 

UNION: 合并两个查询

UNION将两个查询的结果合并为一个结果。

select * from cust_info
union
select * from cust_infobak;
  cust_no  | cust_name |    cust_card_no    | cust_phoneno | cust_address | cust_type
-----------+-----------+--------------------+--------------+--------------+------------
  14435551 | 张贺                   | 431256197306265320 |  15534343555 | 山西临汾                     | 质押
  14435552 | 刘明                   | 371452199303034312 |  18967756743 | 陕西延安                     | 信用
  14435550 | 王吉                   | 12022519960321531X |  15122511874 | 天津武清                     | 抵押
  14435553 | 李华                   | 52112119860621421X |  15833355455 | 湖北武汉                     | 抵押
  14435554 | 郑青                   | 213456199102275341 |  13054546567 | 江西南昌                     | 质押

要显示重复的行,您可以使用UNION ALL

select * from cust_info
union all
select * from cust_infobak;
  cust_no  | cust_name |    cust_card_no    | cust_phoneno | cust_address | cust_type
-----------+-----------+--------------------+--------------+--------------+------------
  14435550 | 王吉                    | 12022519960321531X |  15122511874 | 天津武清                     | 抵押
  14435551 | 张贺                    | 431256197306265320 |  15534343555 | 山西临汾                     | 质押
  14435552 | 刘明                    | 371452199303034312 |  18967756743 | 陕西延安                     | 信用
  14435551 | 张贺                    | 431256197306265320 |  15534343555 | 山西临汾                     | 质押
  14435552 | 刘明                    | 371452199303034312 |  18967756743 | 陕西延安                     | 信用
  14435553 | 李华                    | 52112119860621421X |  15833355455 | 湖北武汉                     | 抵押
  14435554 | 郑青                    | 213456199102275341 |  13054546567 | 江西南昌                     | 质押

INTERSECT: 检索两个查询的交集

INTERSECT仅选择两个查询操作数中都存在的值。

select * from cust_info
intersect
select * from cust_infobak;
  cust_no  | cust_name |    cust_card_no    | cust_phoneno | cust_address | cust_type
-----------+-----------+--------------------+--------------+--------------+------------
  14435551 | 张贺                    | 431256197306265320 |  15534343555 | 山西临汾                     | 质押
  14435552 | 刘明                    | 371452199303034312 |  18967756743 | 陕西延安                     | 信用

EXCEPT:从另一个查询中排除一个查询的结果

EXCEPT选择存在于第一个查询操作数中但不存在于第二个查询操作数中的值。

select cust_no from cust_info
except
select cust_no from cust_infobak;
  cust_no
------------
  14435550

排序查询

按一列对数据进行排序

select * from cust_info order by cust_phoneno asc;--升序排列, asc可以省略
select * from cust_info order by cust_phoneno desc;--降序排列

按多列对数据进行排序

ORDER BY m,n按列对行先进行m排序,然后对列具有相同m值的行,按照n排序。

select * from tb order by b asc,a desc;
  a |  b   |  c
----+------+-------
  7 | NULL | NULL
  6 | NULL |    1
  5 | NULL |    0
  2 |    0 |    1
  1 |    0 |    0
  4 |    1 |    1
  3 |    1 |    0

限制行数

可以使用LIMIT减少数据的查询量。

select * from tb limit 3;

用于并发控制的行级锁定SELECT FOR UPDATE

SELECT FOR UPDATE语句用于通过控制对表的一行或多行的并发访问来对事务进行排序。

它通过锁定选择查询返回的行来工作,这样试图访问这些行的其他事务被迫等待锁定这些行的事务完成。这些其他事务根据尝试读取锁定行的值的时间有效地放入队列。

因为这种排队发生在读取操作期间,如果多个并发执行的事务尝试访问相同的数据,会阻止该选择的结果,hubble还可以防止可能发生的事务重试。

有关如何使用它的示例,请参阅SELECT FOR UPDATE

可组合性查询

使用选择子句作为选择查询

可以将选择子句用作选择查询而无需更改。

例如,构造select * from tb是一个选择子句。它也是一个有效的选择查询,因此可以通过附加分号用作独立语句。

select * from tb;
 a |  b   |  c
----+------+-------
  1 |    0 |    0
  2 |    0 |    1
  3 |    1 |    0
  4 |    1 |    1
  5 | NULL |    0
  6 | NULL |    1
  7 | NULL | NULL

使用表表达式作为选择子句

例如,表达式TABLE empSELECT * FROM emp是等效的选择子句。

同样,SQL连接表达式emp e JOIN dept d ON e.deptno= d.deptno是一个表表达式。您可以将其转换为有效的选择子句,从而成为有效的选择查询,如下所示:

table emp e JOIN dept d ON e.deptno= d.deptno;
select * from emp e JOIN dept d ON e.deptno= d.deptno;

使用选择查询作为表表达式

可以将选择查询(或选择子句)用作表表达式,方法是将其括在括号中,从而形成子查询。

要使其表表达式有效,可以将其括在括号中,如下所示:

select cust_name from (select * from cust_info limit 2);
select e.ename 
from  emp e
join (select * from dept ) as d
  on e.deptno = d.deptno;