一、数据库的根本操作

(一) 对形式进行操作

1) 创立形式

假如咱们想创立表的时分便是形式.表

CREATE SCHEMA myschema;

2)删去形式

  1. 删去空的schema
drop schema myschema
  1. 删去含有表的schema, 能够将下面的表格一举删去
drop schema myschema cascade

(二)对表进行操作

1) 创立表

创立表的一般格局是:

create table schema.students(
column1  类型 【束缚条件】,
column2  类型 【束缚条件】,
...
[束缚条件]
 )

I 束缚条件

i 创立束缚

在 SQL 中,咱们有如下束缚:

  • NOT NULL– 指示某列不能存储 NULL 值。只能写在类型后边
  • UNIQUE– 确保某列的每行必须有仅有的值。能够写在类型后边 , 也能够当成函数写在column后边的束缚条件中。
 create table students (
      name text,
      age int,
      unique (name)
   )
create table students1(
  name  text  unique)

如需命名 UNIQUE 束缚,并界说多个列的 UNIQUE 束缚,咱们应当运用如下的语法, 优点是能够一同界说多个字段的束缚条件, 一同命名是为了咱们在删去这些束缚条件的时分能够一同删去

create table students (
 id int ,
 name text,
 age int,
 studyno int,
 constraint uc_idno unique(id, name, studyno)
 );

删去的办法是:

alter table students drop constraint uc_idno;
--alter table students add constraint uc_idno unique(id, name, studyno)-- 添加束缚的办法
  • PRIMARY KEY– NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有仅有标识,有助于更容易更快速地找到表中的一个特定的记载。运用办法同unique相似 , 一个表中的束缚条件或许不只需一个。
  • FOREIGN KEY– 确保一个表中的数据匹配另一个表中的值的参照完整性。 创立办法有三种分别是:
-- 直接再类型后边添加 todo ....
  create table students (
     id int foreign key references person(id)-- 不晓得什么情况老是报错 还有待讲究
     )
--  直接columns后加上
create table students (
      id int ,
      name text,
      age int,
      studyno int,
       foreign key(id) references person(pid) --  person里边的pid 必须加上unique的束缚
);
--  起别号加外键
create table students (
 id int,
 constraint foreignid  foreign key(id)  references person(id))
  • CHECK– 确保列中的值契合指定的条件。 有两种运用办法
    -- 第一种是直接类型后边加上check函数 
       create students12(
     id  int check(id> 0)
     )
     -- column后边加
    create table studentsmm(
     id  int, 
     check(id > 0)
    );
    --别号 
       create table studentsmm(
     id  int, 
      constraint checkuid check(id > 0)
    );
    
  • DEFAULT– 规定没有给列赋值时的默认值。
create table test(
     id  int default 0,
      orderdate date default getdate() --运用体系值
 )
ii 修正束缚
  1. 添加束缚 通常有两种办法 , 一种是直接add :

     alter table students  add check (id>0)
     alter table students add foreign key(id) references person(id);
     alter table students add primary key(id);
     alter table students add unique(id)
    

    还有一种是add constraint:

     alter table table姓名  add constraint 束缚名   束缚条件
     -- 如 :  alter table students add foreign key(id) references person(id);
    

    最后还有特别的两种default 跟not null

     alter table students alter id set  default 1
      alter table students alter id set not null
    
  2. 修正束缚: sql中想要修正束缚条件一般咱们运用的办法是先删去再添加, 相似 于这种

  alter TABLE test_yt.students drop constraint students_check;
ALTER TABLE test_yt.students ADD CONSTRAINT students_check CHECK (id>3)
  1. 废除束缚 一般选用的是drop constraint
    alter table talename drop constraint  束缚姓名
    -- alter table students drop constraint students_pkey
    
    其中有两个特别的 default not null
     alter table students alter id drop default
     alter table students alter id drop not null
    

2) 修正表

  1. 修正表姓名 //留意假如是形式下面的表rename的时分 rename to 的时分不需要带上那个形式名
 alter table test_yt.students rename to student4
  1. 修正列名
    alter table test_yt.student4 rename column name to namealias
  1. 修正column的字段长度
ALTER TABLE test_yt.student4 ALTER COLUMN name   type varchar(40)
  1. 添加column
ALTER TABLE products ADD COLUMN description text;
  1. 删去column
ALTER TABLE products DROP COLUMN description;
  1. 添加束缚
ALTER TABLE products ADD CONSTRAINT 束缚名 束缚条件
  1. 删去束缚
ALTER TABLE products DROP CONSTRAINT some_name;

3)删去表

drop table student

4) 添加表的别号

有两种写法, 一种是as alias 还有直接是在表名后边加上alias,一旦咱们用了别号之后在子句中咱们就不能运用原有的表名了

select * from test_yt.students1 s where s.name is null;
select * from test_yt.students1 as s where s.name is nullselect * from test_yt.students1 as s where test_yt.students1.name is null  --这是过错的

(三)对表中数据增删查改

留意对表中数据进行再操作的时分是不需要加上table的 , 只需对表进行操作的时分才能够

1) 添加数据

-- 1.针对特定的column
insert into student(id,name,age) values(1,'张三',18);
-- 2. 照着 column的次序刺进数据的时分就能够不加column了, 多条数据刺进的时分, 只需要后边加逗号就好了  
insert into student values(1,'zhangsan',10),(2, 'test', 12)

2) 删去数据

 delete from test_yt.student4 where name='hello'

3) 查找数据

SELECT 列名,列名
FROM 表名

4) 修正数据

update student set name='李四' where id=1

二、常用的数据类型

(一)数值类型

姓名 存储尺寸 描绘 规模
smallint 2字节 小规模整数 -32768 to +32767
integer 4字节 整数的典型挑选 -2147483648 to +2147483647
bigint 8字节 大规模整数 -9223372036854775808 to +9223372036854775807
decimal 可变 用户指定精度,准确 最高小数点前131072位,以及小数点后16383位
numeric 可变 用户指定精度,准确 最高小数点前131072位,以及小数点后16383位
real 4字节 可变精度,不准确 6位十进制精度
double precision 8字节 可变精度,不准确 15位十进制精度
smallserial 2字节 自动添加的小整数 1到32767
serial 4字节 自动添加的整数 1到2147483647
bigserial 8字节 自动增长的大整数 1到9223372036854775807

(二)日期类型

postgresql小结

(三)字符类型

姓名 描绘
character varying(n),varchar(n) 有约束的变长
character(n),char(n) 定长,空格填充
text 无限变长
longtext 极大的文本数据
blob 二进制长文本
longblob 二进制极长的文本

三、常用的函数汇总

(一)数字函数

1) avg

 select avg(age) from student

2) max

 select max(age) from student

3) min

 select min(age) from student

4) sum

 select sum(age) from student

4) gratest

  select greatest (1,2,3);
  select greatest (age, id) from names;-- 选出最需大的那一列

5)latest 最小的

  select latest (1,2,3);

5)sqrt 平方根

select sqrt(25);

6)abs绝对值

select abs(-25);

7)round

select round(1.23)

8)ceil 向上取整

select ceil(1.23)

9)floor 向下取整

select floor(1.59)

10)count 回来指定列值的数目 null不计入

select count(age) from names

(二)字符串函数

1) length 相关

函数 回来类型 描绘 示例 成果
length(string) int string中字符的数目 length('jose') 4
bit_length(string) int 字符串的位 bit_length('jose') 32
char_length(string)character_length(string) int 字符串中的字符个数 char_length('jose') 4

2) encode、 decode相关

函数 回来类型 描绘 示例 成果
decode(stringtext,formattext) bytea 把用string表明的文本里边的二进制数据解码。format选项和encode相同。 decode('MTIzAAE=', 'base64') \x3132330001
encode(databytea,formattext) text 把二进制数据编码为文本表明。支撑的格局有:base64,hex,escapeescape转换零字节和高位设置字节为八进制序列(“`nnn`) 和双反斜杠。 encode(E'123\000\001', 'base64') MTIzAAE=
md5(string) text 核算string的MD5散列,以十六进制回来成果。 md5('abc') 900150983cd24fb0 d6963f7d28e17f72

3) 字符串衔接

函数 回来类型 描绘 示例 成果
concat(str"any"[,str"any"[, ...] ]) text 衔接一切参数的文本表明。NULL 参数被疏忽。 concat('abcde', 2, NULL, 22) abcde222
concat_ws(septext,str"any"[,str"any"[, ...] ]) text 衔接一切参数,可是第一个参数是分隔符,用于将一切参数分隔。NULL 参数被疏忽。 concat_ws(',', 'abcde', 2, NULL, 22) abcde,2,22

4) 字符串拼接函数

函数 回来类型 描绘 示例 成果
string||string text | 字符串衔接 `’Post’ ‘greSQL’` PostgreSQL
string||non-stringnon-string||string |text 带有一个非字符串输入的字符串衔接 `’Value: ‘ 42` Value: 42

5 替换函数

函数 回来类型 描绘 示例 成果
regexp_replace(stringtext,patterntext,replacementtext[,flagstext]) text 替换匹配 POSIX 正则表达式的子字符串。 regexp_replace('Thomas', '.[mN]a.', 'M') ThM
replace(stringtext,fromtext,totext) text 把字符串string里出现地一切子字符串from替换成子字符串to replace('abcdefabcdef', 'cd', 'XX') abXXefabXXef
overlay(stringplacingstringfromint[forint]) text 替换子字符串 overlay('Txxxxas' placing 'hom' from 2 for 4) Thomas
replace(stringtext,fromtext,totext) text 把字符串string里出现地一切子字符串from替换成子字符串to replace('abcdefabcdef', 'cd', 'XX') abXXefabXXef

5 字符串截取

函数 回来类型 描绘 示例 成果
substring(string[fromint] [forint]) text 截取子字符串 substring('Thomas' from 2 for 3) hom
substr(string,from[,count]) text 抽取子字符串。和substring(stringfromfromforcount))相同 substr('alphabet', 3, 2) ph

6) 大小写

函数 回来类型 描绘 示例 成果
lower(string) text 把字符串转化为小写 lower('TOM') tom
upper(string) text 把字符串转化为大写 upper('tom') TOM

7) trim相关

函数 回来类型 描绘 示例 成果
trim([leading|trailing| both] [characters] fromstring) text 从字符串string的最初/结尾/两头删去只包括characters中字符 (缺省是空白)的最长的字符串 trim(both 'x' from 'xTomxx') Tom
trim([leading| trailing| both] [from]string[, characters] ) text trim()的非标准版别 trim(both from 'xTomxx', 'x') Tom
btrim(stringtext[,characterstext]) text string最初和结尾删去只包括characters中字符(缺省是空白)的最长字符串。 btrim('xyxtrimyyx', 'xy') trim
ltrim(stringtext[,characterstext]) text 从字符串string的最初删去只包括characters中字符(缺省是一个空白)的最长的字符串。 ltrim('zzzytrim', 'xyz') trim
rtrim(stringtext[,characterstext]) text 从字符串string的结尾删去只包括characters中字符(缺省是个空白)的最长的字符串。 rtrim('trimxxxx', 'x') trim

8)方位相关的函数

函数 回来类型 描绘 示例 成果
position(substringinstring) int 指定子字符串的方位 position('om' in 'Thomas') 3
strpos(string,substring) int 指定的子字符串的方位。和position(substringinstring)相同,不过参数次序相反。 strpos('high', 'ig') 2
left(strtext,nint) text 回来字符串的前n个字符。当n是负数时, 回来除最后|n|个字符以外的一切字符。 left('abcde', 2) ab
right(strtext,nint) text 回来字符串中的后n个字符。当n是负值时, 回来除前|n|个字符以外的一切字符。 right('abcde', 2) de

9) 字符串填充

函数 回来类型 描绘 示例 成果
rpad(stringtext,lengthint[,filltext]) text 运用填充字符fill(缺省时为空白), 把string填充到length长度。 假如string现已比length长则将其从尾部切断。 rpad('hi', 5, 'xy') hixyx
lpad(stringtext,lengthint[,filltext]) text 经过填充字符fill(缺省时为空白), 把string填充为length长度。 假如string现已比length长则将其尾部切断。 lpad('hi', 5, 'xy') xyxhi

10)其他字符串函数

函数 回来类型 描绘 示例 成果
repeat(stringtext,numberint) text string重复number repeat('Pg', 4) PgPgPgPg
split_part(stringtext,delimitertext,fieldint) text 根据delimiter分隔string回来

(三)日期函数

1) 当时日期时刻:

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(precision)
CURRENT_TIMESTAMP(precision)
LOCALTIME
LOCALTIMESTAMP
LOCALTIME(precision)
LOCALTIMESTAMP(precision)

CURRENT_TIMECURRENT_TIMESTAMP回来带有时区的值;LOCALTIMELOCALTIMESTAMP回来不带时区的值。

CURRENT_TIME,CURRENT_TIMESTAMP,LOCALTIME,LOCALTIMESTAMP能够有挑选地获取一个精度参数,该精度导致成果的秒数域园整到指定小数位。 假如没有精度参数,将给予所能得到的全部精度。 一些比方:

SELECT CURRENT_TIME;
Result: 14:39:53.662522-05
SELECT CURRENT_DATE;
Result: 2001-12-23
SELECT CURRENT_TIMESTAMP;
Result: 2001-12-23 14:39:53.662522-05
SELECT CURRENT_TIMESTAMP(2);
Result: 2001-12-23 14:39:53.66-05
SELECT LOCALTIMESTAMP;
Result: 2001-12-23 14:39:53.662522

2) exact 相关

SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 20

其中hour 能够换成其他的字段, 如:

ISODOW  --表明是周几
MILLISECONDS  --秒
minute ---分
month
quarter 
week
year

(四)聚合函数

窗口函数在和当时行相关的一组表行上履行核算。 这相当于一个能够由聚合函数完结的核算类型。但不同于常规的聚合函数, 运用的窗口函数不会导致行被分组到一个单一的输出行;行保留其独立的身份。 在后台,窗口函数能够访问的不止查询成果的当时行。 下面的比方是依照不同的部分求取平均值: over()函数是用来标注规模的 , 假如不写 partition by,默认是一切行,

SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
  depname  | empno | salary |          avg
-----------+-------+--------+-----------------------
 develop   |    11 |   5200 | 5020.0000000000000000
 develop   |     7 |   4200 | 5020.0000000000000000
 develop   |     9 |   4500 | 5020.0000000000000000
 develop   |     8 |   6000 | 5020.0000000000000000
 develop   |    10 |   5200 | 5020.0000000000000000
 personnel |     5 |   3500 | 3700.0000000000000000
 personnel |     2 |   3900 | 3700.0000000000000000
 sales     |     3 |   4800 | 4866.6666666666666667
 sales     |     1 |   5000 | 4866.6666666666666667
 sales     |     4 |   4800 | 4866.6666666666666667
(10 rows)

下面是依照部分进行薪酬的排名,rank()的时分必定要写order by,不然rank列的值都是1

 select depname, empno,salary, rank() over (partition by depname order by salary desc) from test_yt.salaries

表 9-53. 通用窗口函数

函数 回来类型 描绘
row_number() bigint 在其分区中的当时行号,从1计
rank() bigint 有间隔的当时行排名;与它的第一个相同行的row_number相同
dense_rank() bigint 没有间隔的当时行排名;这个函数计数对等组。
percent_rank() double precision 当时行的相对排名: (rank– 1) / (总行数 – 1)
cume_dist() double precision 当时行的相对排名:(前面的行数或与当时行相同的行数)/(总行数)

(五) 聚合函数

一个聚合函数从多个输入行中核算出一个成果。比方,咱们有在一个行调集上核算count(数目),sum(总和),avg(均值),max(最大值),min(最小值)的函数。 如:

SELECT max(temp_lo) FROM weather;
函数 参数类型 回来类型 描绘
array_agg(expression) 恣意 参数类型的数组 输入值,包括空,衔接到一个数组
avg(expression) smallint,int,bigint,real,double precision,numeric, orinterval 关于任何整数类型输入,成果都是numeric类型。 关于任何浮点输入,成果都是double precision类型。 不然和输入数据类型相同。 一切输入值的均值(算术平均)
bit_and(expression) smallint,int,bigint, orbit 和参数数据类型相同 一切非 NULL 输入值的按位与(AND),假如全部输入值皆为 NULL ,那么成果也为 NULL 。
bit_or(expression) smallint,int,bigint, orbit 和参数数据类型相同 一切非 NULL 输入值的按位或(OR),假如全部输入值皆为 NULL ,那么成果也为 NULL 。
bool_and(expression) bool bool 假如一切输入值都是真,则为真,不然为假。
bool_or(expression) bool bool 假如至少有一个输入值为真,则为真,不然为假。
count(*) bigint 输入行数
count(expression) 恣意 bigint 核算一切输入行中满足expression不为 NULL 的行数。
every(expression) bool bool 等效于bool_and
json_agg(expression) any json 聚合值作为JSON数组
json_object_agg(name,value) (any, any) json 聚合姓名/值对作为JSON对象
max(expression) 恣意数组、数值、字符串、日期/时刻类型 和参数数据类型相同 有输入行中expression的最大值
min(expression) 恣意数组、数值、字符串、日期/时刻类型 和参数数据类型相同 一切输入行中expression的最小值
string_agg(expression,delimiter) (text,text) or (bytea,bytea) 和参数数据类型相同 输入值衔接成为一个字符串,用分隔符分隔
sum(expression) smallint,int,bigint,real,double precision,numeric,interval, ormoney 关于smallintint参数,输出类型为bigint。 关于bigint参数,输出类型为numeric,不然和参数数据类型相同。 一切输入行的expression总和。
xmlagg(expression) xml xml 衔接 XML 值

四、运算符

(一)算数操作符

操作符 描绘 比方 成果
+ 2 + 3 5
- 2 - 3 -1
* 2 * 3 6
/ 除(整数除法将切断成果) 4 / 2 2
% 模(求余) 5 % 4 1
幂(指数运算) 2.0 ^ 3.0 8
|/ 平方根 |/ 25.0 5
||/ 立方根 ||/ 27.0 3
! 阶乘 5 ! 120
!! 阶乘(前缀操作符) !! 5 120
@ 绝对值 @ -5.0 5
& 二进制 AND 91 & 15 11
| 二进制 OR 32| 3 35
# 二进制 XOR 17 # 5 20
~ 二进制 NOT ~1 -2
<< 二进制左移 1 << 4 16
>> 二进制右移 8 >> 2 2

(二) 位串操作符

操作符 描绘 比方 成果
|| 衔接 B'10001' ||B'011' 10001011
& 位与 B'10001' & B'01101' 00001
| 位或 B'10001'| B'01101' 11101
# 位异或 B'10001' # B'01101' 11100
~ 位非 ~ B'10001' 01110
<< 位左移 B'10001' << 3 01000
>> 位右移 B'10001' >> 2 00100

(三) 逻辑运算符

AND | | OR | | NOT

(四)比较运算符略

五、常用的关键字或常用子句

(一) with 子句

(试了一下postgresl好像是不支撑with句子的) with 句子相当于建立了一张暂时虚拟表,可是不会被物理创立,用完即毁掉;每个WITH子句中的辅助句子可所以一个SELECT,INSERT,UPDATEDELETE

WITH moved_rows AS (
    DELETE FROM products
    WHERE
        "date" >= '2010-10-01' AND
        "date" < '2010-11-01'
    RETURNING *
)
INSERT INTO products_log
SELECT * FROM moved_rows;

(二)distinct子句

假如声明晰SELECT DISTINCT,那么就从成果会集删去一切重复的行 (每个有重复的组都保留一行)。

select distinct on (depname) depname  from test_yt.salaries

(三)all子句

all 与distinct相反

select all  (depname) depname  from test_yt.salaries

postgresql小结

(四)union子句

UNION 操作符用于合并两个或多个 SELECT 句子的成果并集 , 然后去除重复项, 假如不需要去除重复项的话 , 只需加上union all就能够了

 insert into test_yt.students1 values(1,'xiaoming'),(2,'xiaohua'),(3,'xiaoli');
 insert into test_yt.students values(1,'xiaoming'),(2,'xiaohuamao'),(3,'xiaoli');
 insert into test_yt.students values (4,'xiaozhangs');
  insert into test_yt.students1 values (4,'xiaozhangs1')
select name from test_yt.students1 union select name from test_yt.students

postgresql小结

(五)INTERSECT子句

INTERSECT便是查找有相同选项的交集

select name from test_yt.students1 INTERSECT  select name from test_yt.students

(六)except子句

这个句子便是再第一个select的成果中去掉第二个select的中的成果, 然后剩余的便是最终的成果

 insert into test_yt.students1 values(1,'xiaoming'),(2,'xiaohua'),(3,'xiaoli');
 insert into test_yt.students values(1,'xiaoming'),(2,'xiaohuamao'),(3,'xiaoli');
 insert into test_yt.students values (4,'xiaozhangs');
  insert into test_yt.students1 values (4,'xiaozhangs1')
select name from test_yt.students1 EXCEPT  select name from test_yt.students

成果是xiaohua和xiaozhangs1

(七)limit 和offset

limit约束了在前面几条中进行查询 , 1代表只查询第一条 ,all的话, 默认没有约束 , offset 代表偏移前面的几行 , 比方offset 1 代表从第二行开始查找

select * from test_yt.students limit 1 offset 1

(八)exists

EXISTS 运算符用于判断查询子句是否有记载,假如有一条或多条记载存在回来 True,不然回来 False。exists 能够和not连用

select name from test_yt.students where  exists (select name from test_yt.students1 where id  =1)

(九)in

in操作符答应您在 WHERE 子句中规定多个值。找出契合in 规模中存在的行,not in相反

select name from test_yt.students where name in('xiaoming','xiaoli','xiaosan')

(十)any,all

any 表明恣意一个 ,all代表一切

select id from test_yt.students where id > any (select id from test_yt.students1 )

(十一) join

语法:

SELECT column1, column2, ...
FROM table1
JOIN table2 ON condition;

students列表是:

postgresql小结

students1的列表是:

postgresql小结

1) join| inner join

postgresql小结

postgresql小结

2) left join

postgresql小结

postgresql小结

3) right join 和left 相反

postgresql小结

4 )full outer join

postgresql小结

postgresql小结

(十二)is null 、is not null

 select * from test_yt.students1 where name is null;
  select * from test_yt.students1 where name is not null

(十三)like含糊查询

占位符:%  恣意个数字符   _一个字符
查询 用户名以‘S’最初的职工信息
   Select * from emp where ename like 'S%'
查询用户名第二个字母是‘A’的职工信息
   select * from emp where ename like '_A%'
查询用户名第三个字母是‘A’的职工信息
   select * from emp where ename like '__A%'
包括A
   select * from emp where ename like '%A%'

六、视图

在 SQL 中,视图是根据 SQL 句子的成果集的可视化的表。 视图包括行和列,就像一个实在的表。视图中的字段便是来自一个或多个数据库中的实在的表中的字段。 您能够向视图添加 SQL 函数、WHERE 以及 JOIN 句子,也能够呈现数据,就像这些数据来自于某个单一的表相同。

(一) 创立视图

CREATE VIEW view_name AS
SELECT column_name(s)  
FROM table_name  
WHERE condition
create view myview as select * from test_yt.students s ;
 select * from  myview

我觉得视图是有点像引证类型的变量的 , 假如表格的内容发生改变的话,view 里边查询的值也是会跟着改变的

(二) 查询视图

 select * from  myview

(三) 修正视图

1) rename

alter view myview rename to myviews;

2)其他略

(四) 删去视图

drop view myview

七、易错留意点

(一)聚合函数运用场景

不能用于where子句中可是能够再having子句中运用 ,首要原因是- where 是在聚合之前选取行也便是操控哪些行进行聚合核算, having是在聚合之后才进行选取

SELECT city FROM weather WHERE temp_lo = max(temp_lo);     过错

正确的运用办法是:

SELECT city FROM weather
    WHERE temp_lo = (SELECT max(temp_lo) FROM weather);

(二)having 子句和where子句的区别

HAVING去除了一些不满足条件的组行。它与WHERE不同:WHERE在运用GROUP BY之前过滤出单独的行, 而HAVING过滤由GROUP BY创立的行,见第三条的表格 比方:select depname from test_yt.salaries group by depname having depname=’dev’ having的话便是先分组,有dev personal 以及sales, 然后去掉不满足条件的personal,sales 假如运用where的话 , 便是先找到depname等于dev的, 然后再进行分组

(三)group by的留意点

group by的时分必须确保前面select 的column名 跟后边划分的共同,比方:

postgresql小结

这样的一张表 , 假如我直接

select * from test_yt.salaries group by depname 报错

正确的应该是

select depname from test_yt.salaries group by depname

(四)union子句和intersect、except

select_statement是任何不带ORDER BY,LIMIT,FOR NO KEY UPDATE,FOR UPDATE,FOR SHARE, 或FOR KEY SHARE子句的SELECT句子。