当数据量较小时,使用EXCEL处理数据更方便和高效。
但若是数据量很大,或是需要对较多数据进行复杂的处理,SQL的效率便显现出来了。
在这里记录常用的SQL语句,我的SQL水平比较初级哈🙂
/* 将1个已有数据表中的全部数据提取到1个新创建的表中, 表的新建与备份*/
CREATE TABLE 新表名 AS
SELECT * FROM 已有旧表名
/* 下句与上句的结果相同*/
SELECT *
INTO 新表名
FROM 已有旧表名;
/*在表1中插入一行新数据*/
INSERT INTO 表1名 (列1名, 列2名, 列3名, ……) VALUES (值1, 值2, 值3, ……);
/*删除列*/
alter table 表名 drop column 列名
/*删除行*/
DELETE FROM 表名
WHERE 列名 = ‘要删除行对应的字段’;
/* 将3个列名相同的表纵向合成1个新表,每个表的列名和结构需相同*/
CREATE TABLE 新表名 AS
SELECT * FROM 表1名
UNION ALL SELECT * FROM 表2名
UNION ALL SELECT * FROM 表3名
/* 如不加UNION后面的ALL,则合并后会删除重复数据*/
/* 求不同表的交集,即提取表1和表2共有的内容*/
SELECT * FROM 表1名
INTERSECT SELECT * FROM 表2名
/* 求不同表的差集,即提取:删除表1和表2共有内容后的表1内容*/
SELECT * FROM 表1名
EXCEPT SELECT * FROM 表2名
/* 查1张表共有多少行数据*/
SELECT COUNT(*) FROM 表名
SELECT CEILING(1.1)
/* 向上取整,返回2*/SELECT FLOOR(1.9)
/* 向下取整,返回1*/SELECT round(1.567,0)
/* 四舍五入取整,返回2*//* 将不同的表依据相同的行名横向合成1个新表, 类似excel的vlookup函数*/
CREATE TABLE 新表名 AS
SELECT * FROM 表1名 AS 表1别名
LEFT OUTER JOIN 表2名 AS 表2别名
ON (表1别名.与表2内容匹配的列名 = 表2别名.与表1内容匹配的列名);
/*如果使用INNER JOIN 替换 OUTER JOIN ,则提取结果为两个表中共有的内容,不会出现NULL值*/
/* 使用 RIGHT 时FROM 子句中写在右侧的表是主表*/
/* to_char函数与CAST函数*/
/*将原有值(非字符串)转换成自定义格式的字符串类型*/
SELECT to_char( 列名, '自定义格式' ) FROM 表名
/* 下例将时间格式转换为仅显示年月的字符串格式, 如将2020-01-01转为 ‘2020-01’ */
SELECT to_char(time, 'YYYY-MM' ) FROM 表名
/* CAST(转换前的值 AS 想要转换的数据类型),下例是将字符串日期转换为日期类型, 表面看不出差别*/
SELECT CAST(列名 AS DATE ) FROM 表名
/*COALESCE — 将NULL转换为其他值*/
/*把表1的列1中的空值NULL全部转为XXX */
UPDATE 表1名
SET 列1名 = COALESCE(列1名, 'XXX')
或是:
SELECT COALESCE(列1名, 'XXX')
FROM 表1名
/*提取表1前5行的数据*/
SELECT * FROM 表1名
limit 5
/*提取表1的所有列名*/
select column_name
from information_schema.columns
where table_name = '表1名';
/*下语句的意思是:从表1中提取3列数据,
提取出的数据以列3降序排列(不加DESC则会以升序排列),
并且这些数据需同时满足2个条件:列1=XX和列2=1。
有时候因为某些格式限制,眼见是XX,但输入XX却提取不出数据,
因此可尝试使用“LIKE ‘%XX%’”来提取XX数据*/
SELECT 列1名, 列2名, 列3名 FROM 表1名
where 列名1 LIKE '%XX%' AND 列2名 = 1
ORDER BY 列3名 DESC;
/* LIKE使用说明*/
LIKE 'XX%' 会将以XX开头的数据提取出来,如XXYY,XX123;
LIKE '%XX' 会将以XX结尾的数据提取出来,如YYXX,123XX;
LIKE '%XX%' 会将含有XX的所有数据提取出来。
/*下语句的意思是:从表1中提取4列数据,
这些数据需同时满足2个条件:列5=1和列6=2,
提取出的数据会删除重复的列2、列3、列4组合,
提取出的列1变成计数列, 即在某个列2、列3、列4组合下,列1中包含的与之相对应的的数据量。
例子:假设列2是时间、列3是姓名、列4地点,“2020.1月/张三/在体育场”构成了一个组合,
假如列1是事件,如果”在2020.1月内,张三在体育场“进行了跑步、打篮球、踢足球三次运动,
count的计算结果是3。*/
CREATE TABLE 表2名 AS
select count(列1名), 列2名, 列3名, 列4名 from 表1名
where 列5名 = 1 AND 列6名 = 2
GROUP BY 列2名, 列3名, 列4名
/*上面的结果告诉我们:某人在某地在某时间段内做了几件事,
接下来如果想知道:在所有时间段内,某人在某地做了几件事,
仍旧假设列3是姓名、列4地点,
可以在上面提取结果的表2上再次提取数据。*/
select count(列名3), 列名3, 列名4 from 表2名 GROUP BY 列3名, 列4名
/*以上2个语句可组合为1个*/
select count(列名3), 列名3, 列名4
from
(select count(列1名), 列2名, 列3名, 列4名 from 表1名
where 列5名 = 1 AND 列6名 = 2
GROUP BY 列2名, 列3名, 列4名) AS 表2名
GROUP BY 列3名, 列4名
/*上面这个语句和下面这个语句的相同点是:它们提取的结果行数相同,提取的列3和列4也相同;
不同点是:如果在2020.1月(同一时间段),张三打了两次篮球,
上一句会记录1次(其中1个GROUP BY用于删除同一时间的重复值),
下一句会记录2次*/
select count(列名1), 列名3, 列名4 from 表1名
where 列名5 = 1 AND 列名6 = 2
GROUP BY 列名3, 列名4
/*使用DISTINCT可删除列中重复的数据*/
SELECT DISTINCT 列名 FROM 表名;
/*下语句和上语句会得到同样的结果, 如上所述, GROUP BY也有删除重复数据的作用*/
SELECT 列名 FROM 表名
GROUP BY 列名;
/*下语句会删除列1和列2组合后的重复数据*/
SELECT DISTINCT 列1名, 列2名
FROM 表名;
/*将两列内容合成为一列* /
/*提取两列数据* /
select e.last_name , e.first_name
from name AS e
/*提取1列数据,以单引号’为分隔(在psql中,要显示单引号’需要键入两个单引号”),
||
意为合并数据* /select e.last_name ||''''|| e.first_name as name
from name e
/*触发器设置* /
/*当某个表发生某事件时(INSERT、UPDATE、DELETE等),其他工作表会相应发生改变*/
/*psql中的触发器设定*/
/*创建两个表*/
drop table if exists test1;
drop table if exists test2;
CREATE TABLE test1(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50)
);
CREATE TABLE test2(
Num INT NOT NULL,
NAME TEXT NOT NULL
);
/*首先需要创建触发器函数*/
CREATE OR REPLACE FUNCTION tfun() RETURNS TRIGGER AS $trigger1$
BEGIN
INSERT INTO test2 VALUES (new.ID, new.name);
RETURN NEW;
END;
$trigger1$ LANGUAGE plpgsql;
/*创建触发器,注意!触发器名应与表名有联系,方便后期查找*/
CREATE TRIGGER trigger_test1
AFTER INSERT ON test1 FOR EACH ROW
EXECUTE PROCEDURE tfun();
/*触发器检验,在test1表中插入信息时,ID和NAME会自动添补到test2表中*/
INSERT INTO test1 (ID,NAME,AGE,ADDRESS)VALUES (1, 'Bene', 18, 'China' );
select * from test1;
select * from test2;
/*查找数据库中已有的触发器*/
SELECT * FROM pg_trigger;
/*删除触发器,
DROP TRIGGER 触发器名 on 所在表名
*/DROP TRIGGER trigger_test1 on test1;
/*计算一串字符中有几个逗号*/
SELECT LENGTH('i,10ve,y0u')-LENGTH(e) FROM
(SELECT REPLACE ('i,10ve,y0u',',','')AS e) AS a
/*以姓名最后两个字母进行排序*/
/*使用
substring
,'..$'
中两个点代表两个字母,符号$表示从最后开始计算*/SELECT first_name FROM
(SELECT first_name,substring(first_name,'..$' ) AS e FROM name
ORDER BY e,first_name) AS c
/*使用
RIGHT
*/SELECT first_name FROM name ORDER BY RIGHT(first_name,2);
To be continued…