Apache Tajo 简明教程

Apache Tajo - SQL Queries

本章解释了以下重要的查询。

  1. Predicates

  2. Explain

  3. Join

让我们继续并执行查询。

Predicates

谓词是一种用于评估 true/false 值和 UNKNOWN 的表达式。谓词用于 WHERE 子句和 HAVING 子句以及需要布尔值的其他结构的搜索条件中。

IN predicate

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

Syntax

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

Query

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

Result

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

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

该查询返回 mytable 中 id 为 2、3 和 4 的学生的记录。

Query

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

Result

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

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 Predicate

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

该模式可包含任何形式的通配符,例如:

  1. 下划线符号(_),可用于替换要测试的值中的任何单个字符。

  2. 百分比符号(%),可替换要测试的值中的零个或多个字符的任何字符串。

Syntax

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

Query

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

Result

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

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

查询返回那些以“A”开头的学生姓名,来自 mytable 的记录。

Query

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

Result

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

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

查询返回那些以“a ”为第二个字符开头的学生姓名,来自 mytable 的记录。

Using NULL Value in Search Conditions

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

Syntax

Predicate
IS [NOT] NULL

Query

select name from mytable where name is not null;

Result

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

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

在此,结果为 true,故它从表格中返回所有名称。

Query

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

default> select name from mytable where name is null;

Result

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

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

Explain

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

Logical Plan Query

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

Result

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

explain

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

  1. Target list

  2. Out schema

  3. In schema

Global Plan Query

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)

Result

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

global plan

在此,全局计划显示执行块 ID、执行顺序及其信息。

Joins

SQL 连接用于将来自两个或多个表的行合并在一起。以下是不同类型的 SQL 连接:

  1. Inner join

  2. { LEFT | RIGHT | FULL } OUTER JOIN

  3. Cross join

  4. Self join

  5. Natural join

考虑以下两个表,以执行连接操作。

Table1 − 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

Table2 − customer_order

Id

Order Id

Emp Id

1

1

101

2

2

102

3

3

103

4

4

104

5

5

105

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

Inner Join

内部连接从两个表中选择所有行,当两个表中的列之间有匹配项时。

Syntax

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

Query

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

Result

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

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

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

Left Outer Join

左外联接保留“左表”中的所有行,而不管是否有与“右表”中的某行匹配的行。

Query

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

Result

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

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

在此示例中,左外联接返回来自 customers(左表)表的 name 列行和来自 customer_order(右表)表中的 empid 列匹配的行。

Right Outer Join

右外联接保留“右表”中的所有行,而不管是否有与“左表”中的某行匹配的行。

Query

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

Result

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

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

在此示例中,右外联接返回来自 customer_order(右表)表的 empid 行和来自 customers 表的与 name 列匹配的行。

Full Outer Join

全外联接保留来自左表和右表的所有行。

Query

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

Result

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

full outer join

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

Cross Join

这会返回来自两个或更多联接表的记录集的笛卡尔积。

Syntax

SELECT *  FROM table1  CROSS JOIN table2;

Query

select orderid,name,address from customers,customer_order;

Result

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

cross join

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

Natural Join

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

Syntax

SELECT * FROM table1 NATURAL JOIN table2;

Query

select * from customers natural join customer_order;

Result

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

natural join

在此示例中,存在列 id,它是这两个表之间的公共属性。使用该公共属性, Natural Join 联接这两个表。

Self Join

SQL 自联接用于将一个表连接到它自身,就像该表是两个表一样,在 SQL 语句中临时重命名至少一个表。

Syntax

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

Query

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

Result

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

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

该查询将客户表连接到它自身。