Apache Tajo - SQL 查询

本章解释以下重要查询。

  • Predicates(谓词)
  • Explain
  • Join

让我们继续执行查询。

谓词

谓词是一个表达式,用于评估真/假值和未知值。 谓词用于 WHERE 子句和 HAVING 子句以及其他需要布尔值的结构的搜索条件。

IN 谓词

确定要测试的表达式的值是否与子查询或列表中的任何值匹配。 子查询是一个普通的 SELECT 语句,其结果集包含一列和一行或多行。 此列或列表中的所有表达式必须与要测试的表达式具有相同的数据类型。

语法

IN::= 
<expression to test> [NOT] IN (<subquery>) 
| (<expression1>,...)

查询

select id,name,address from mytable where id in(2,3,4);

结果

上述查询将生成以下结果。

id,  name,   address 
------------------------------- 
2,  Amit,  12 old street 
3,  Bob,   10 cross street 
4,  David, 15 express avenue 

该查询从 mytable 返回学生 ID 2,3 和 4 的记录。

查询

select id,name,address from mytable where id not in(2,3,4);

结果

上述查询将生成以下结果。

id,  name,  address 
------------------------------- 
1,  Adam,   23 new street 
5,  Esha,   20 garden street 
6,  Ganga,  25 north street 
7,  Jack,   2 park street 
8,  Leena,  24 south street 
9,  Mary,   5 west street 
10, Peter,  16 park avenue 

上面的查询返回 mytable 中学生不在 2,3 和 4 中的记录。

Like 谓词

LIKE 谓词将用于计算字符串值的第一个表达式中指定的字符串(称为要测试的值)与用于计算字符串值的第二个表达式中定义的模式进行比较。

该模式可以包含通配符的任意组合,例如 −

  • 下划线符号 (_),可以用来代替要测试的值中的任何单个字符。

  • 百分号 (%),它替换要测试的值中任何包含零个或多个字符的字符串。

语法

LIKE::= 
<expression for calculating the string value> 
[NOT] LIKE 
<expression for calculating the string value> 
[ESCAPE <symbol>] 

查询

select * from mytable where name like ‘A%'; 

结果

上述查询将生成以下结果。

id,  name,  address,     age,  mark 
------------------------------- 
1,  Adam,  23 new street,  12,  90 
2,  Amit,  12 old street,  13,  95

该查询从 mytable 中返回姓名以"A"开头的学生的记录。

查询

select * from mytable where name like ‘_a%'; 

结果

上述查询将生成以下结果。

id,  name,  address,    age,  mark 
——————————————————————————————————————- 
4,  David,  15 express avenue,  12,  85 
6,  Ganga,  25 north street,    12,  55 
7,  Jack,  2 park street,       12,  60 
9,  Mary,  5 west street,       12,  75 

该查询从 mytable 中返回姓名以"a"作为第二个字符开头的学生的记录。

在搜索条件中使用 NULL 值

现在让我们了解如何在搜索条件中使用 NULL 值。

语法

Predicate  
IS [NOT] NULL 

查询

select name from mytable where name is not null; 

结果

上述查询将生成以下结果。

name 
------------------------------- 
Adam 
Amit 
Bob 
David 
Esha 
Ganga 
Jack 
Leena 
Mary 
Peter  
(10 rows, 0.076 sec, 163 B selected) 

这里,结果为 true,因此它返回表中的所有名称。

查询

现在让我们检查带有 NULL 条件的查询。

default> select name from mytable where name is null; 

结果

上述查询将生成以下结果。

name 
------------------------------- 
(0 rows, 0.068 sec, 0 B selected) 

Explain

Explain用于获取查询执行计划。 它显示了语句的逻辑和全局计划执行。

逻辑计划查询

explain select * from mytable;  
explain 
-------------------------------  
   => target list: default.mytable.id (INT4), default.mytable.name (TEXT), 
      default.mytable.address (TEXT), default.mytable.age (INT4), default.mytable.mark (INT4) 
   
   => out schema: {
   (5) default.mytable.id (INT4), default.mytable.name (TEXT), default.mytable.address (TEXT), 
      default.mytable.age (INT4), default.mytable.mark (INT4)
   } 
   
   => in schema: {
	(5) default.mytable.id (INT4), default.mytable.name (TEXT), default.mytable.address (TEXT), 
      default.mytable.age (INT4), default.mytable.mark (INT4)
   }

结果

上述查询将生成以下结果。

Explain

查询结果显示给定表的逻辑计划格式。 逻辑计划返回以下三个结果 −

  • Target list
  • Out schema
  • In schema

global 全局计划查询

explain global select * from mytable;  
explain 
------------------------------- 
------------------------------------------------------------------------------- 
Execution Block Graph (TERMINAL - eb_0000000000000_0000_000002) 
------------------------------------------------------------------------------- 
|-eb_0000000000000_0000_000002 
   |-eb_0000000000000_0000_000001 
------------------------------------------------------------------------------- 
Order of Execution 
------------------------------------------------------------------------------- 
1: eb_0000000000000_0000_000001 
2: eb_0000000000000_0000_000002 
-------------------------------------------------------------------------------  
======================================================= 
Block Id: eb_0000000000000_0000_000001 [ROOT] 
=======================================================  
SCAN(0) on default.mytable 
   
   => target list: default.mytable.id (INT4), default.mytable.name (TEXT), 
      default.mytable.address (TEXT), default.mytable.age (INT4), default.mytable.mark (INT4) 
   
   => out schema: {
	(5) default.mytable.id (INT4), default.mytable.name (TEXT),default.mytable.address (TEXT), 
      default.mytable.age (INT4), default.mytable.mark (INT4)
   } 
   
   => in schema: {
	(5) default.mytable.id (INT4), default.mytable.name (TEXT), default.mytable.address (TEXT), 
      default.mytable.age (INT4), default.mytable.mark (INT4)
   }  
======================================================= 
Block Id: eb_0000000000000_0000_000002 [TERMINAL] 
======================================================= 
(24 rows, 0.065 sec, 0 B selected) 

结果

上述查询将生成以下结果。

Global Plan

这里,全局计划显示了执行块ID、执行顺序及其信息。

连接

SQL 连接用于组合两个或多个表中的行。 以下是不同类型的 SQL 连接 −

  • Inner join
  • { LEFT | RIGHT | FULL } OUTER JOIN
  • Cross join
  • Self join
  • Natural join

考虑以下两个表来执行联接操作。

表1 -Customers(客户)

Id Name Address Age
1 Customer 1 23 Old Street 21
2 Customer 2 12 New Street 23
3 Customer 3 10 Express Avenue 22
4 Customer 4 15 Express Avenue 22
5 Customer 5 20 Garden Street 33
6 Customer 6 21 North Street 25

表2 − customer_order

Id Order Id Emp Id
1 1 101
2 2 102
3 3 103
4 4 104
5 5 105

现在让我们继续对上述两个表执行 SQL 连接操作。

内连接

当两个表中的列之间存在匹配时,内联接会选择两个表中的所有行。

语法

SELECT column_name(s) FROM table1 INNER JOIN table2 ON table1.column_name = table2.column_name;

查询

default> select c.age,c1.empid from customers c inner join customer_order c1 on c.id = c1.id; 

结果

上述查询将生成以下结果。

age,  empid 
------------------------------- 
21,  101 
23,  102 
22,  103 
22,  104 
33,  105 

查询匹配两个表中的五行。 因此,它返回第一个表中匹配的行年龄。

左外连接

左外连接保留"左"表的所有行,无论"右"表是否有匹配的行。

查询

select c.name,c1.empid from customers c left outer join customer_order c1 on c.id = c1.id;

结果

上述查询将生成以下结果。

name,       empid 
------------------------------- 
customer1,  101 
customer2,  102 
customer3,  103 
customer4,  104 
customer5,  105 
customer6,

这里,左外连接返回来自customers(左)表的name列行和来自customer_order(右)表的empid列匹配行。

右外连接

右外连接保留"右"表的所有行,无论"左"表中是否有匹配的行。

查询

select c.name,c1.empid from customers c right outer join customer_order c1 on c.id = c1.id;

结果

上述查询将生成以下结果。

name,      empid 
------------------------------- 
customer1,  101 
customer2,  102 
customer3,  103 
customer4,  104 
customer5,  105

此处,右外连接返回 customer_order(right) 表中的 empid 行以及customers 表中 name 列匹配的行。

完全外连接

完全外连接保留左表和右表中的所有行。

查询

select * from customers c full outer join customer_order c1 on c.id = c1.id;

结果

上述查询将生成以下结果。

Full Outer Join

该查询返回customers 和customer_order 表中的所有匹配和不匹配行。

交叉连接

这将返回两个或多个连接表中记录集的笛卡尔积。

语法

SELECT *  FROM table1  CROSS JOIN table2;

查询

select orderid,name,address from customers,customer_order;

结果

上述查询将生成以下结果。

交叉连接

上面的查询返回表的笛卡尔积。

自然连接

自然连接不使用任何比较运算符。 它不像笛卡尔积那样进行连接。 仅当两个关系之间至少存在一个共同属性时,我们才能执行自然连接。

语法

SELECT * FROM table1 NATURAL JOIN table2;

查询

select * from customers natural join customer_order; 

结果

上述查询将生成以下结果。

自然连接

这里,两个表之间存在一个公共列 ID。 使用该公共列,自然连接连接两个表。

自连接

SQL SELF JOIN 用于将一个表与其自身连接起来,就好像该表是两个表一样,在 SQL 语句中临时重命名至少一个表。

语法

SELECT a.column_name, b.column_name...  
FROM table1 a, table1 b  
WHERE a.common_filed = b.common_field  

查询

default> select c.id,c1.name from customers c, customers c1 where c.id = c1.id; 

结果

上述查询将生成以下结果。

id,   name 
------------------------------- 
1,   customer1 
2,   customer2 
3,   customer3 
4,   customer4 
5,   customer5 
6,   customer6 

该查询将客户表与其自身连接起来。