sql语法DEMO5

举报
HW_TEST 发表于 2025/11/13 16:20:30 2025/11/13
【摘要】 sql语法DEMO5

1. 数据库对象管理及SQL语法1

由于疫情管控,某小区进行封锁,收集了RESIDENTS居民表,包含姓名、年龄、性别、楼栋信息。

--创建表

create table RESIDENTS(name varchar(20),age int,sex char(1),building int);

--导入数据

insert into RESIDENTS VALUES('a',0,'m',02);

insert into RESIDENTS VALUES('b',24,'m',03);

insert into RESIDENTS VALUES('c',25,'f',05);

1、为了方便按楼栋给婴儿送纸尿裤,查出每栋age<1的数量,最后显示楼栋信息和对应数量

select building,count(*) from residents where age<1 group by building;

2、由于每栋楼各个年龄段的人都有,故按age年龄段分组[0-18),[18-35),[35-55),[55-maxvalues)形成age_group,每个组命名group1,group2,group3,group4

select age , case when age<18 then 'group1'

when age>=18 and age<35 then 'group2'

when age>=35 and age<55 then 'group3'

 else 'group4' end as age_group from residents;

3、age_group按每组人数多少排序,查询出age_group、人数、最大年龄、最小年龄、平均年龄(平均年龄向下取整)

select  case when  age<18 then 'group1'

when  age>=18 and age<35 then 'group2'

when age>=35 and age<55 then 'group3'

 else 'group4' end as age_group,count(age) as "人数",

max(age) as "最大年龄",min(age) as  "最小年龄",floor(avg(age)) as  "平均年龄"

from residents group by age_group order by "人数" desc;

1、 由于需要每天要送食物,增加如下每个年龄段所需食物营养价值表,需要统计出该小区每天总营养值

 

select sum(case when age<18 then 5 when age>=18 and age<35 then 7

when age>=35 and age<55 then 6

else 5 end) as "每天总营养值" from residents;

--如果需要计算每个人需要的总营养值如下:

select age,case when age<18 then 'group1'

when age>=18 and age<35 then 'group2'

when age>=35 and age<55 then 'group3'

else 'group4' end as age_group,

case when age_group='group1' then 5

when age_group='group2' then 7

when age_group='group3' then 6

when age_group='group5' then 5

end as nutrition_value from residents;

2、 按楼栋求出每栋楼所需营养值

select building,sum(case when age<18 then 5

when age>=18 and age<35 then 7

when age>=35 and age<55 then 6

else 5 end) as "每栋楼所需营养价值"

from residents group by building;

2. 数据库对象管理及SQL语法2

当前有一张订单表lineitem,具体字段如下

L_ORDERKEY BIGINT NOT NULL --订单key

L_PARTKEY BIGINT NOT NULL --配件key

L_SUPPKEY BIGINT NOT NULL --供应商key

L_LINENUMBER BIGINT NOT NULL --流水号

L_QUANTITY float8 null --数量

L_EXTENDEPPRICE float8 NOT NULL --出厂价

L_DISCOUNT float8 NOT NULL --折扣

L_TAX float8 NOT NULL --税点

L_RETURNFLAG CHAR(1) NOT NULL --原返标志

L_LINESTATUS CHAR(1) NOT NULL --明细

L_SHIPDATE DATE NOT NULL --发货日期

L_COMMITDATE DATE NOT NULL --预计到达日期

L_ARRIVALDATE DATE NOT NULL --达到时间

L_ORDERSTRATEGY CHAR(32) NOT NULL --订单处理策略

L_TRANSPORTROUTE CHAR(32) NOT NULL --运输路径

L_COMMENT VARCHAR(64) NOT NULL --备注

--数据导入

 

1、创建分区表,根据上述字段信息创建分区表,按L_SHIPDATE分区,按年分1993,1994,1995,1996,1997,1998,1999,分区名称分别为L_SHIPDATE_1,第二个分区名称为L_SHIPDATE_2以此类推,使用L_ORDERKEY进行哈希分布,建表完成后执行上方数据导入代码,进行数据导入

create table lineitem(

L_ORDERKEY BIGINT NOT NULL ,

L_PARTKEY BIGINT NOT NULL ,

L_SUPPKEY BIGINT NOT NULL ,

L_LINENUMBER BIGINT NOT NULL,

L_QUANTITY float8 null,

L_EXTENDEPPRICE float8 NOT NULL,

L_DISCOUNT float8 NOT NULL ,

L_TAX float8 NOT NULL,

L_RETURNFLAG CHAR(1) NOT NULL ,

L_LINESTATUS CHAR(1) NOT NULL ,

L_SHIPDATE DATE NOT NULL ,

L_COMMITDATE DATE NOT NULL ,

L_ARRIVALDATE DATE NOT NULL ,

L_ORDERSTRATEGY CHAR(32) NOT NULL ,

L_TRANSPORTROUTE CHAR(32) NOT NULL ,

L_COMMENT VARCHAR(64) NOT NULL)

distribute by hash(L_ORDERKEY)

partition by range(L_SHIPDATE)

(partition L_SHIPDATE_1 values less than ('1993-01-01 00:00:00'),

partition L_SHIPDATE_2 values less than ('1994-01-01 00:00:00'),

partition L_SHIPDATE_3 values less than ('1995-01-01 00:00:00'),

partition L_SHIPDATE_4 values less than ('1996-01-01 00:00:00'),

partition L_SHIPDATE_5 values less than ('1997-01-01 00:00:00'),

partition L_SHIPDATE_6 values less than ('1998-01-01 00:00:00'),

partition L_SHIPDATE_7 values less than ('1999-01-01 00:00:00'),

partition L_SHIPDATE_8 values less than ('2000-01-01 00:00:00')

);

 

2、查询表的schema名称,展示表名,schema名称

select tablename,schemaname from pg_tables where tablename='lineitem';

select c.relname,n.nspname from pg_class c ,pg_namespace n where c.relnamespace=n.oid and c.relname='lineitem';

3、产看表分布节点的oid,展示表名,nodeoids

select relname,nodeoids from pg_class,pgxc_class where oid=pcrelid where relname='lineitem';

1、 查看表所在实例的信息

select relname,pgxc_node.* from pg_class,pgxc_class,pgxc_node where pg_class.oid=pgxc_class.pcrelid and cast(pgxc_class.nodeoids as varchar(20))=cast(pgxc_node.oid as varchar(20)) and relname='p_table';

3. 数据库连接

1、 创建user2用户,user2用户需要具备创建数据库的权限

create user user2 createdb password 'Huawei@123';

2、 查看用户的连接数上限

select rolname,rolconnlimit from pg_roles where rolname='user2';

3、 设置user2用连接数为100

alter user user2 connection limit 100;

4、 查询postgres用户连接数上限,显示库,上限数量

select datname,datconnlimit from pg_database where datname=’postgres’;

 

5、 查询postgres用户已使用的会话连接数

select count(datname) from pg_stat_activity where datname=’postgres’;

--如果查询已结束的会话数量,筛选state

-- select count(datname) from pg_stat_activity where datname=’postgres’ and state=’idle’;

6、 查看所有用户已使用的会话连接数

Select count(datname) from pg_stat_activity;

7、 查询库最大连接数

show max_connections;

8、 查询会话状态,显示datidpidstate

select datid,pid,state from pg_stat_activity;

4. 安全审计

1、 创建user3用户,密码’test@123’

create user user3 password 'test@123';

2、 给用户授予查看审计权限

alter user user3 with auditadmin; 

3、 登录postgres,创建统一审计策略adt1,对所有数据库执行create审计操作

--切换到实例管理界面的参数管理模块,修改enable_security_policy为on;

--创建统一审计策略

create audit policy adt1 privileges create;

4、 登录postgres,创建审计策略adt2,对所有数据库执行select审计操作

create audit policy adt2 access select;

5、 登录postgres,创建表tb1,创建审计策略adt3,仅审计记录用户root,在执行针对表tb1资源进行的select、insert、delete操作数据库创建审计策略

--创建表

create table tb1(c1 int);

--创建资源标签标记tb1表

create resource label tb1_label add table(tb1);

--创建统一审计

create audit policy adt3 access select on label(tb1_label),insert on label(tb1_label),delete on label(tb1_label) filter on roles(root);

6、 为统一审计对象策略adt1,添加描述’audit policy for tb1’

alter audit policy adt1 comments 'audit policy for tb1';

7、 修改adt1,使之对IP地址为’10.20.30.40’的场景生效

alter audit policy adt1 modify(filter on ip('10.20.30.40'));

8、 禁用统一审计策略adt1

alter audit policy adt1 disable;

9、 删除策略adt1、adt2、adt3和相应的资源标签,级联删除用户user1

--删除审计策略

drop audit policy adt1,adt2,adt3;

--删除资源标签

drop resource label tb1_label;

--级联删除用户

drop user user1 cascade;

5. 存储过程

基于以下信息表,完成以下实验要求。

--创建表

CREATE TABLE APS_STUDENTS(LOGID SERIAL,STARTIME TIMESTAMP(0) NOT NULL,PRIMARY KEY(LOGID));

1、 编写存储过程,生成记录,传入学生个数,学生LOGID从1000000开始,starttime为当前时间

create or replace procedure pro_s(num int)

as

begin

for id in 100000 .. (100000 + num-1) loop

insert into aps_students values(id,now());

dbe_output.print_line('id='||id); --|| 用于做字符拼接

end loop;

end;

/

2、 用上一操作初始化90000学生

call pro_s(9000);

3、 查出aps_students表中初始化学生个数

select count(*) from aps_students;

6. 触发器

本题根据教授详情表和部门表完成相应触发器创建使用

--创建表

create table teacher(id integer primary key,name varchar(50) not null,deptnd integer not null,tetle varchar(50) not null);

create table department(id integer primary key,name varchar(50) not null,number_of_senior integer default 0);

--导入数据

insert into department values(1,'physics',0),(2,'mathmetics',0),(3,'chemistry',0);

insert into teacher values(1,'tom',1,'associate professor'),(2,'bill',1,'professor'),(11,'eiston','3','associate professor');

1、 创建Tri_update_D触发器,如果修改Number_of_senior字段时提示“不能随便修改部门教授职称人数”,如果已经有了Tri_update_D触发器,则删除后再重建

--创建触发器函数

create or replace function print_info() returns trigger

as

$$

begin

dbe_output.print_line('不能随便修改不能教授职称人数');

return null;--返回null表示不允许修改,返回old表示可以修改

end;

$$ language plpgsql;

--当触发器存在时将触发器删除,然后创建触发器

drop trigger if exists Tri_update_D on department;

create trigger Tri_update_D before update of number_of_senior on department for each row execute procedure print_info();

2、 禁止触发器,修改DEPARTMENT表中D=1的NUMBER_OF_SENIOR=10,并查出表中数据

--禁用触发器

alter table department disable trigger Tri_update_D;

--执行更新操作

update department set number_of_senior=10 where id=1;

--查询部门表,查看更新结果

select * from department;

3、 启动触发器,修改DEPARTMENT表中ID=1的NUMBER_OF_SENIOR=20

--启动触发器

alter table  department enable trigger Tri_update_D;

--执行更新操作

update department set number_of_senior=20 where id=1;

--查询部门表,查看更新结果

select * from department;

7. 性能调优

通常的SQL优化会通过参数调优的方式进行调整,例如如下参数

set enable_fast_query_shipping = off;

set enable_stream_operator = on;

请根据以下表完成数据库优化

--建表

create table tb_user(stu_no int,stu_name varchar(32),age int,hobby_type int) distribute by hash(age);

--插入数据

insert into tb_user select id,'xiaoming'||(random()*50+10)::int,

(random()*50+10)::int,

(random()*5+1)::int

from (select generate_series(1,100000)id)tb_user;

1、 收集tb_user的统计信息

analyze tb_user;

2、 为下面两个查询语句创建索引,让执行计划和索引最合理

sql1:explain analyze select * from tb_user where age=29 and stu_name='xiaoming';

sql2:explain analyze select * from tb_user where  stu_no=100 and age=29;

--SQL1

select gs_index_advise('select * from tb_user where age=29 and stu_name=’'xiaoming'’');

create index age_name on tb_user(stu_name,age);

--SQL2

select gs_index_advise('select * from tb_user where stu_no=100 and age=29');

create index age_no on tb_user(stu_no,age);

3、 在上题的基础上,三种不同的方式使如下SQL不走索引

explain analyze select * from tb_user where stu_no=100 and age=29;

--1.通过hint干预优化不走索引

explain analyze select /* + tablescn(tb_user)  */ * from tb_user where stu_no=100 and age=29;

--2.调大index开销

set cpu_index_tuple_cost = 100000;

--3.直接禁用索引

alter index age_no,age_name unusable;

--4.禁止优化器使用indexscan:

set enable_indexscan=off

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。