一、Hive简介
1、hive的概念
1)它是一种数据仓库
a、数据仓库:数据仓库系统是一个信息提供平台,他从业务处理系统获得数据,主要以星型模型和雪花模型进 行数据组织,并为用户提供各种手段从数据中获取信息和知识。
从功能结构划分,数据仓库系统至少应该包含三个关键部分:
数据获取(Data Acquisition)、
数据存储(Data Storage)、
数据访问(Data Access)。
b、数据库仓库的架构:
2)它是一种数据分析引擎
本质上: SQL ---> MapReduce ---> YRAN --> HDFS ---> 结果
Hive是一个翻译器,借助Hive引擎将SQL语句转成MR程序且构建于HDFS上的一个数据仓库。
3)它支持SQL(SQL99的一个子集)
可以写SQL语句来分析
2、hive在hadoop生态圈中的地位
3、hive的体系结构
三、Hive数据模型(如何组织数据方法:database、table、视图、文件)
Hive将为每个数据库创建一个目录。(HDFS上创建一个与之对应的目录)
演示与验证:
验证两种方式:
1)$hive> dfs -lsr /;
2)hdfs dfs -lsr /;
该数据库中的表将存储在数据库目录的子目录中。
例外情况是默认数据库中的表,它没有自己的目录。
database ---> 目录
table ---> 目录(database子目录)
一、默认路径:
数据库目录是在属性hive.metastore.warehouse.dir指定的顶级目录下创建的,一般指
/user/hive/warehouse/路径下
这个路径在hive的不同安装模式意义是不一样的:
1)嵌入模式:指hive所在的Linux文件系统上的目录;
2)本地模式和远程模式:指分布式文件系统上的目录
二、自定义路径
创建database时需要显示指定:
hive> CREATE DATABASE financials
> LOCATION '/my/preferred/directory';
三、添加描述信息
hive> CREATE DATABASE financials
> COMMENT 'Holds all financial tables';
四、查看database的详情
hive> DESCRIBE DATABASE financials;
五、数据库的基本操作
在hive中创建数据库和table
创建数据库
------------------------------------
1、create database testdb;
2、create database testdb2 comment '描述信息';
3、自定义路径:
create database testdb3 location '/user/cutsom/testdb3';
4、创建指定数据库属性的数据库
create database mydb2 comment 'this is my db2' location '/user/custom/mydb2' with dbproperties ('creator'='Suben','date'='2020-05-31');
删除数据库:
-------------------------------------
drop database db2;
注意事项:如果数据库不为空
1、先删除数据库中的表
2、级联删除
显示当前所使用的数据库:
-------------------------------------
1、查看当前使用的数据库:
SELECT current_database();
2、查看hive ddl创建语句:
hive> show create database mydb2;
OK
CREATE DATABASE `mydb2`
COMMENT
'This is my db2'
LOCATION
'hdfs://bigdata:9000/user/custom/mydb2'
WITH DBPROPERTIES (
'creator'='Suben',
'date'='2020-05-31')
Time taken: 0.092 seconds, Fetched: 8 row(s)
修改数据库属性
-------------------------------------
1、先创建表,并插入数据
//创建表
create table stu(id int,name string,age int);
//插入数据(转成MR程序)
insert into stu(id,name,age) values(1,'suben',20);
2、修改database
alter database mydb2 set dbproperties ('edited-by'='suben','date'='2020-06-01');
四、表的基本操作及其分类
0、表基本操作
创建表
-------------------------------------
1、在testdb2创建表:没指定任何分隔符
create table student(
id int,
name string,
age int,
phone string
);
2、创建带有指定的分隔符表employees
------------------------------------
CREATE TABLE employees (
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING, FLOAT>,
address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001'
COLLECTION ITEMS TERMINATED BY '\002'
MAP KEYS TERMINATED BY '\003'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
注意事项:
1)、ROW FORMAT DELIMITED必须出现在任何其他子句之前, STORED AS子句除外。
2)、字符\001是^A的八进制代码。ROW FORMAT DELIMITED FIELDS
TERMINATED BY '\001'表示Hive将使用^A字符来分隔字段
3)、字符\002是^B的八进制代码。ROW FORMAT DELIMITED
COLLECTION ITEMS TERMINATED BY '\002'表示Hive将使用^B字符来分隔集合项
4)、字符\003是^C的八进制代码。ROW FORMAT DELIMITED
MAP KEYS TERMINATED BY '\003' 表示Hive将使用^C字符来分隔map键和值。
5)、LINES TERMINATED BY '…' 子句和STORED AS … 子句,不需要 ROW FORMAT
DELIMITED关键字。
6)、用户可以覆盖字段、集合和键值分隔符,但仍然使用默认的文本文件格式故STORED AS子句通常不需要指定,默认的TEXTFILE文件格式。
7)、这些规范只影响Hive在读取文件时所期望看到的内容。
除了少数有限的情况外,数据文件的正确格式取决于您。
举一个例子:
CREATE TABLE IF NOT EXISTS employee_internal (
name STRING COMMENT 'this is optinal column comments',
work_place ARRAY<STRING>,-- table column names are NOT case sensitive
gender_age STRUCT<gender:STRING,age:INT>,
skills_score MAP<STRING,INT>, -- columns names are lower case
depart_title MAP<STRING,ARRAY<STRING>>-- No "," for the last column
)
COMMENT 'This is an internal table'-- This is optional table comments
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|' -- Symbol to seperate columns
COLLECTION ITEMS TERMINATED BY ','-- Seperate collection elements
MAP KEYS TERMINATED BY ':' -- Symbol to seperate keys and values
STORED as TEXTFILE;
添加数据:
load data local inpath 'file:///root/hivedatas/employee.txt' overwrite into table employee_internal;
查看数据:
select * from employee_internal;
3、通过CTAS或者CTE来创建表
1)包含表结构与数据:
create table employee as select * from employee_internal;
2)只包含表结构:
create table employee as select * from employee_internal where 1=2;
或者使用like来:
create table employee like employee_internal;
修改表结构:列名称、新增列
--------------------------------------
1)重命名表,常用于备份
ALTER TABLE cte_employee RENAME TO cte_employee_backup;
2)修改表的属性(comment、owner等)
ALTER TABLE c_employee SET TBLPROPERTIES('comment'='New comments');
3)修改表的行的格式
ALTER TABLE employee_internal SET SERDEPROPERTIES('field.delim' = '$');
4)修改表的行文件格式
ALTER TABLE c_employee SET FILEFORMAT RCFILE;
5)启动或禁用表的保护机制
> ALTER TABLE c_employee ENABLE NO_DROP;
> ALTER TABLE c_employee DISABLE NO_DROP;
> ALTER TABLE c_employee ENABLE OFFLINE;
> ALTER TABLE c_employee DISABLE OFFLINE;
6)修改列的类型或者列的描述信息
>ALTER TABLE employee_internal CHANGE employee_name name string COMMENT 'updated' FIRST;
>ALTER TABLE employee_internal CHANGE name employee_name string AFTER gender_age;
7)增加新列
ALTER TABLE c_employee ADD COLUMNS (work string);
8)改变一张表所有的列
ALTER TABLE c_employee REPLACE COLUMNS (name string);
查看表|列的描述信息
--------------------------------------
通过show 查看:
1)show tables;
2)show tables '*stu*'; //使用正则表达式显示符合条件的表
3)show table extended like '*emp*';
4)show column in employee_internal; //显示employee_internal所有列
5)SHOW CREATE TABLE employee_internal;
6)SHOW TBLPROPERTIES employee_internal;
通过desc查看:
1)desc employee;
2)desc extended emp;
3)desc formatted emp;
插入与更新表
--------------------------------------
insert into stu(id,name,age) values(2,"苏江明",30);
删除表|删除表数据
--------------------------------------
1)DROP TABLE IF EXISTS empty_ctas_employee; //删除表结构与数据
2)TRUNCATE TABLE cte_employee; --只删除表数据
1、内部表:类似于MySQL中的表,用于存储结构化数据
特点:表的所有权是属于hive的,同时表的数据的整个生命周期都是有hive控制
生命周期:从数据的生产到数据的消亡
表的删除,就会引发数据的删除
类型:1)普通的表:与MySQL中的表类似
2)分区表(Partition):按照某个字段对数据进行分区(对应目录)
3)桶表(Bucket) :对某个字段按照hash算法进行分桶(对应的文件)
1)创建表:没有带指定分隔符
create table if not exists emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int
);
查看表详情:
1、dfs -lsr /user;
2、desc emp;
3、desc extended emp;
4、desc formatted emp;
加载数据:在hive的cli中执行
1、load data local inpath 'file:///root/emp.csv' overwrite into table emp;
2、load data inpath '/root/emp.csv' overwrite into table emp;
区别:
1、是将Linux本地文件系统上的数据复制到hive表中(ctrl + c)
2、将hdfs上的数据移动到hive表中(ctrl + x)
查询emp表中数据:
hive> select * from emp;
结果:
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL
原因:创建表的时候没有任何分割符
解决方法:创建表时添加分隔符
注意:分隔符的指定与数据原文件的格式保持一致
2)创建带有分隔符的表
create table if not exists delimited_emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int
)
row format delimited fields terminated by ','
lines terminated by '\n';
与没有带分隔符的表的区别:
Storage Desc Params:
field.delim ,
line.delim \n
serialization.format ,
加载数据:
load data inpath '/root/emp.csv' overwrite into table emp;
查询数据:
select * from delimted_emp;
删除表:
drop table delimted_emp;
注意:1、删除表时,表对应的目录及其数据被删除
2、MySQL中存储的表的元信息也被删除
2、外部表:
相当于给HDFS上的文件创建了一个链接(快捷方式)
特点:
1)表结构被创建的同时,数据也就存在(数据提前准备好)
2)删除表,数据不会删除,只删除表结构或元信息(mysql中)
3)read-only 只读,不能更改、删除表所对应的hdfs上的数据
4)对应hdfs上是一个目录(由hdfs自己创建的)
5)只是创建了表的元信息(MySQL)
好处:能够对HDFS上的数据进行分析,不用维护数据的增删改
create external table if not exists emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int)
row format delimited fields terminated by ','
lines terminated by '\n'
location '/data/hive/';
3、分区表:
意义:提高查询的性能,优化查询效率
特点:属于内部表,具备内部表所有的特点
分区对应是目录
create table if not exists emp_part(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int
)
partitioned by (deptno int)
row format delimited fields terminated by ','
lines terminated by '\n';
插入数据:
insert into table emp_part partition(deptno=10) select empno,ename,job,mgr,hiredate,sal,comm from emp where deptno=10;
insert into table emp_part partition(deptno=20) select empno,ename,job,mgr,hiredate,sal,comm from emp where deptno=20;
insert into table emp_part partition(deptno=30) select empno,ename,job,mgr,hiredate,sal,comm from emp where deptno=30;
查看SQL的执行计划:查看分区表的查询性能
explain select * from emp_external where deptno=10; --查看外部表的执行计划
OK
STAGE DEPENDENCIES:
Stage-0 is a root stage
STAGE PLANS:
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
TableScan
alias: emp_external
Statistics: Num rows: 1 Data size: 618 Basic stats: COMPLETE Column stats: NONE
Filter Operator
predicate: (deptno = 10) (type: boolean)
Statistics: Num rows: 1 Data size: 618 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: empno (type: int), ename (type: string), job (type: string), mgr (type: int), hiredate (type: string), sal (type: int), comm (type: int), 10 (type: int)
outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7
Statistics: Num rows: 1 Data size: 618 Basic stats: COMPLETE Column stats: NONE
ListSink
Time taken: 0.829 seconds, Fetched: 20 row(s)
explain select * from emp_part where deptno=10; --查看分区表的执行计划
执行计划:
OK
STAGE DEPENDENCIES:
Stage-0 is a root stage
STAGE PLANS:
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
TableScan
alias: emp_part
Statistics: Num rows: 3 Data size: 121 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: empno (type: int), ename (type: string), job (type: string), mgr (type: int), hiredate (type: string), sal (type: int), comm (type: int), 10 (type: int)
outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7
Statistics: Num rows: 3 Data size: 121 Basic stats: COMPLETE Column stats: NONE
ListSink
Time taken: 1.226 seconds, Fetched: 17 row(s)
分区表的基本操作
----------------------------
0)创建分区表
CREATE EXTERNAL TABLE IF NOT EXISTS employee_partitioned (
name STRING COMMENT 'this is optinal column comments',
work_place ARRAY<STRING>,-- table column names are NOT case sensitive
gender_age STRUCT<gender:STRING,age:INT>,
skills_score MAP<STRING,INT>, -- columns names are lower case
depart_title MAP<STRING,ARRAY<STRING>>-- No "," for the last column
)
PARTITIONED BY (year INT, month INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|' -- Symbol to seperate columns
COLLECTION ITEMS TERMINATED BY ','-- Seperate collection elements
MAP KEYS TERMINATED BY ':' -- Symbol to seperate keys and values
STORED as TEXTFILE;
1)增加分区:增加多个静态分区
ALTER TABLE employee_partitioned ADD PARTITION (year=2018, month=11) PARTITION (year=2018,month=12);
2)查看分区信息
SHOW PARTITIONS employee_partitioned;
3)删除分区
ALTER TABLE employee_partitioned DROP IF EXISTS PARTITION (year=2018, month=11);
注意:
-- Drop partition with PURGE at the end will remove completely
-- Drop partition will NOT remove data for external table
-- Drop partition will remove data with partition for internal table
-- Drop all partitions in 2017
ALTER TABLE employee_partitioned DROP IF EXISTS PARTITION (year=2017);
4)重命名分区
ALTER TABLE employee_partitioned PARTITION (year=2018, month=12) RENAME TO PARTITION (year=2018,month=10);
注意:
-- Below is failed
-- Because all partition columns should be specified for partition rename
> --ALTER TABLE employee_partitioned PARTITION (year=2018)
> --RENAME TO PARTITION (year=2017);
静态分区与动态分区区别:
静态分区通常用于外部表,其中包含在HDFS中新添加的数据。在这种情况下,它通常使用日期作为分区列,比如yyyyMMdd。每当新一天的数据到达时,我们就将特定于当天的静态分区(通过脚本)添加到表中,然后就可以立即从表中查询新到达的数据。
对于动态分区,它通常用于内部表之间的数据转换,其中的分区列来自于数据本身;
5)从分区中删除数据。
注意,删除数据不会删除分区信息。为了做一个完整的数据清理,我们可以在删除数据后删除步骤1中描述的分区:
-- For internal table, we use truncate
> TRUNCATE TABLE employee_partitioned PARTITION
(year=2018,month=12);
-- For external table, we have to use hdfs command
> dfs -rm -r -f /user/dayongd/employee_partitioned;
6)向分区表添加常规列。
注意,我们不能添加新的列作为分区列。当从分区表中添加/删除列时,有两种选择:级联和限制。常用的CASCADE选项将相同的更改级联到表中的所有分区。但是,限制是默认的,只将列更改限制为表元数据,这意味着更改将只应用于新分区,而不是现有分区:
ALTER TABLE employee_partitioned ADD COLUMNS (work string) CASCADE;
7)修改现有分区列的数据类型
ALTER TABLE employee_partitioned PARTITION COLUMN(year string);
验证:
DESC employee_partitioned
注意事项:
现在,我们只能更改分区列数据类型。我们不能从分区列中添加/删除列。如果必须更改分区设计,则必须备份并重新创建表,然后迁移数据。此外,我们不能直接将非分区表更改为分区表。
8)改变分区的其他属性的文件格式,位置,保护,和连接有相同的语法来改变表语句:
> ALTER TABLE employee_partitioned PARTITION (year=2018)
> SET FILEFORMAT ORC;
> ALTER TABLE employee_partitioned PARTITION (year=2018)
> SET LOCATION '/tmp/data';
> ALTER TABLE employee_partitioned PARTITION (year=2018) ENABLE
NO_DROP;
> ALTER TABLE employee_partitioned PARTITION (year=2018) ENABLE
OFFLINE;
> ALTER TABLE employee_partitioned PARTITION (year=2018) DISABLE
NO_DROP;
> ALTER TABLE employee_partitioned PARTITION (year=2018) DISABLE
OFFLINE;
> ALTER TABLE employee_partitioned PARTITION (year=2018) CONCATENATE;
4、桶表:根据hash算法对表中的某个字段或列进行hash运算,将hash运算结果相同的放在一个桶里面(对应hdfs是一个个文件)
其目的也是为了提高查询效率
注意:桶的个数不能随便给,防止数据发生倾斜(大部分的数据都会放在一个桶里面,造成数据不均匀分布)
桶的个数遵照一个原则:
1) 一般桶的个数要等于reduce的个数或者开启桶的个数按钮,通常推荐桶的个数等同于2的n次方
数据块:128M,512M文件(hdfs)--> 4个桶
2) hive自动将数据计算计算,分配多少个桶
具体设置:
hive> set hive.reduce.num = 4;
hive> set hive.enforce.bucketing=true;
1)创建普通表并添加数据
----------------------------------------------------
--Prepare table employee_id and its dataset to populate bucket table
CREATE TABLE employee_id (
name STRING,
employee_id INT,
work_place ARRAY<STRING>,
gender_age STRUCT<gender:STRING,age:INT>,
skills_score MAP<STRING,INT>,
depart_title MAP<STRING,ARRAY<STRING>>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':';
-- 添加数据
load data inpath '/data/employee_id.txt' overwrite into table employee_id;
-- 创建桶表
CREATE TABLE employee_id_bucket (
name STRING,
employee_id INT,
work_place ARRAY<STRING>,
gender_age STRUCT<gender:STRING,age:INT>,
skills_score MAP<STRING,INT>,
depart_title MAP<STRING,ARRAY<STRING>>
)
CLUSTERED BY (employee_id) INTO 2 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':';
要定义正确的桶数,我们应该避免每个桶中有太多或太少的数据。更好的选择是接近两个数据块的地方,比如每个桶中有512 MB的数据。作为一种最佳实践,使用2的N次方作为桶的数量。
注意事项:
Bucketing与资料载入过程有密切的关系。要正确地将数据加载到bucket表中,我们需要将最大还原器数量设置为与创建表中指定的bucket数量相同(例如,2),或者启用强制存储
(推荐),如下:
> set map.reduce.tasks = 2; -- 设置与reduce数量一致
> set hive.enforce.bucketing = true; -- This is recommended
-- 添加数据到桶表中
INSERT OVERWRITE TABLE employee_id_buckets SELECT * FROM employee_id;
-- 验证
-- Verify the buckets in the HDFS from shell
$hdfs dfs -ls /user/hive/warehouse/employee_id_buckets
2)创建emp表达的桶表:
------------------------------------------------
create table if not exists emp_bucket(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int
)
clustered by (job) into 4 buckets
row format delimited fields terminated by ','
lines terminated by '\n';
在插入数据前,需要先开启桶表,默认是关闭的
hive>set hive.enforce.bucketing=true
插入数据:通过子查询方式(转成MR程序)
insert into emp_bucket select * from emp;
该SQL语句会转成MR程序交给YARN去执行。
查看执行计划
-----------------------
explain select * from emp_bucket;
5、视图
视图是逻辑数据结构,可以通过隐藏复杂性(如连接、子查询和过滤器)来简化查询。之所以称为逻辑视图,是因为视图只在metastore中定义,而在HDFS中没有内存占用。与关系数据库中的视图不同,HQL中的视图不存储数据或产生数据。一旦创建了视图,它的模式就会立即被冻结。基表的后续更改(例如,添加列)不会反映在视图的模式中。如果删除或更改了基础表,则随后尝试查询表无效。
-- 创建视图
CREATE VIEW IF NOT EXISTS employee_skills
AS
SELECT
name, skills_score['DB'] as DB,
skills_score['Perl'] as Perl,
skills_score['Python'] as Python,
skills_score['Sales'] as Sales,
skills_score['HR'] as HR
FROM employee;
-- 说明:
在创建视图时,不会触发纱线作业,因为这只是一个元数据更改。
但是,在查询视图时将触发作业。要检查视图定义,可以使用SHOW语句。在修改视图定义时,我们可以使用ALTER观点陈述。下面是一些显示、检查和修改视图的示例:
> SHOW VIEWS;
> SHOW VIEWS 'employee_*';
> DESC FORMATTED employee_skills;
> SHOW CREATE TABLE employee_skills; -- this is recommended
> ALTER VIEW employee_skills SET TBLPROPERTIES ('comment'='Aview');
> ALTER VIEW employee_skills as SELECT * from employee;
> DROP VIEW employee_skills;
create view emp_view as select * from emp;
五、hiveserver2和beeline服务
hive --service hiveserver2 &
hive --service beeline
beeline> !connect jdbc:hive2://192.168.215.135:10000/mydb
六、使用Hive-jdbc驱动程序采用jdbc方式访问远程数据仓库
1.创建java模块
2.引入maven
3.添加hive-jdbc依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.suben</groupId>
<artifactId>HiveDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
</project>
4.App
package com.suben.hivedemo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* 使用jdbc方式连接到hive数据仓库,数据仓库需要开启hiveserver2服务。
*/
public class App {
public static void main(String[] args) throws Exception {
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection conn = DriverManager.getConnection("jdbc:hive2://192.168.215.135:10000/mydb2");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("select id , name ,age from t");
while(rs.next()){
System.out.println(rs.getInt(1) + "," + rs.getString(2)) ;
}
rs.close();
st.close();
conn.close();
}
}
七、实现员工表聚合操作
1、按照部分号统计各个部门工资与奖金的总额
select deptno,sum((cast((comm is not null) as int) + sal)) sums from employee group by deptno;
2、按照部分号统计各个部门工资与奖金的总额,并且按照总额进行降序排序
select deptno,sum((cast((comm is not null) as int) + sal)) sums from employee group by deptno order by sums desc;
八、自定义函数(UDF)
转载请注明原文地址:https://ipadbbs.8miu.com/read-2380.html