sql基础知识
1.concat(a,“-”,b):
将a和b列,连接成字符串,用-分割后输出成一列。(分隔符在参数中间)
2.insert into values(),():
插入多列时用逗号分割,不需要在最外层加再加括号。
3.insert ignore into actor values(‘3’,‘ED’,‘CHASE’,‘2006-02-15 12:34:33’):
在insert into 之间加入ignore,表示如果数据存在则不插入。
4.窗口函数:
下面介绍三种用于进行排序的专用窗口函数:
-
RANK()
在计算排序时,若存在相同位次,会跳过之后的位次(如下例子中跳过了2,3)。
例如,有3条排在第1位时,排序为:1,1,1,4······ -
DENSE_RANK()
这就是题目中所用到的函数,在计算排序时,若存在相同位次,不会跳过之后的位次。
例如,有3条排在第1位时,排序为:1,1,1,2······ -
ROW_NUMBER()
这个函数赋予唯一的连续位次(不软相不相同,都会自增,相当于一个自增序号)。
例如,有3条排在第1位时,排序为:1,2,3,4······
其它:SUM()、AVG()、MIN()、MAX():计算窗口内指定列的总和、平均值、最小值和最大值。
LAG()、LEAD():返回指定列在窗口中前一行或后一行的值。
窗口函数用法:
<窗口函数> OVER ( [PARTITION BY <列清单> ]
ORDER BY <排序用列清单>
rows between 开始位置 and 结束位置)
*其中[ ]中的内容可以忽略。
在使用over()窗口函数时,over()函数中的这三个函数可组合使用也可以不使用。
over()函数中如果不使用这三个函数,窗口大小是针对查询产生的所有数据,如果指定了分区,窗口大小是针对每个分区的数据。
使用例子:
SELECT dept_id,
AVG(salary) OVER(PARTITION BY dept_id) as avg_salary,
RANK() OVER(PARTITION BY dept_id ORDER BY salary DESC) as salary_rank
FROM employees;
关于连续类的例子:
某宝店铺连续2天及以上购物的用户及其对应的天数
SELECT
user_id,COUNT(*) days_count
FROM
(SELECT
DISTINCT user_id,sales_date,DENSE_RANK() over(PARTITION by user_id ORDER BY sales_date) rn
FROM
sales_tb) a
GROUP BY
user_id,DATE_ADD(sales_date,INTERVAL - rn day)
HAVING
days_count >=2
ORDER BY
user_id
相关知识:
1)关于INTERVAL
例如,如果sales_date为2022-06-01,rn为2,那么DATE_ADD(sales_date,INTERVAL - rn day)将返回2022-05-30,即2022-06-01减去2天后的日期。
5.用with定义临时表达式
WITH
cte_name1 AS (
-- 第一个临时表达式的定义
),
cte_name2 AS (
-- 第二个临时表达式的定义
),
...
SELECT ...
FROM ...
注意:
1)临时表达式可以是任何有效的Hive查询语句,包括SELECT、JOIN、GROUP BY、ORDER BY等,注意必须是一个完整的select语句。
2)临时表达式在查询中的顺序很重要,因为后续的表达式可以引用前面已定义的表达式。
3)临时表达式的定义仅在WITH语句范围内有效,在主查询之外无法访问。
4)临时表达式可以引用之前定义的临时表达式,但不能递归引用自身。
5) WITH语句可以与其他查询操作一起使用,如WHERE、GROUP BY、ORDER BY等。
具体例子如下:
WITH
filtered_data AS (
SELECT *
FROM sales_table
WHERE date >= '2023-01-01' AND date <= '2023-03-31'
),
monthly_sales AS (
SELECT
month(date) AS sales_month,
SUM(quantity) AS total_quantity
FROM filtered_data
GROUP BY month(date)
)
SELECT sales_month, total_quantity
FROM monthly_sales
ORDER BY sales_month;
6.建表
MYSQL创建数据表的三种方法:
-
常规创建
create table if not exists 目标表 -
复制表格
create 目标表 like 来源表 -
将table1的部分拿来创建table2
create table if not exists actor_name
(
first_name varchar(45) not null,
last_name varchar(45) not null
)
select first_name,last_name
from actor
7.创建索引
1)添加主键
ALTER TABLE tbl_name ADD PRIMARY KEY (col_list);
// 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
2)添加唯一索引(可以null,但是必须唯一)
语法:alter table 表名 add (unique) index 索引名(列名)
ALTER TABLE tbl_name ADD UNIQUE index_name (col_list);
// 这条语句创建索引的值必须是唯一的。
3)添加普通索引
语法:alter table 表名 add index 索引名(列名)
ALTER TABLE tbl_name ADD INDEX index_name (col_list);
// 添加普通索引,索引值可出现多次。
4)添加全文索引
ALTER TABLE tbl_name ADD FULLTEXT index_name (col_list);
// 该语句指定了索引为 FULLTEXT ,用于全文索引。
PS: 附赠删除索引的语法:
DROP INDEX index_name ON tbl_name;
// 或者
ALTER TABLE tbl_name DROP INDEX index_name;
ALTER TABLE tbl_name DROP PRIMARY KEY;
还可以用CREATE来创建索引:
语法:create (unique) index 索引名 on 表名(列名)
CREATE UNIQUE INDEX uniq_idx_firstname ON actor (first_name
);
CREATE INDEX idx_lastname ON actor (last_name
);
上述索引名都是自定义的!
8.根据已有表建创建视图
create view actor_name_view (first_name_v,last_name_v) as
select first_name ,last_name from actor
9.增加列
语法:ALTER TABLE <表名> ADD COLUMN <新字段名> <数据类型> [约束条件] [FIRST|AFTER 已存在的字段名];
例子:ALTER TABLE actor ADD create_date datetime NOT NULL DEFAULT ‘2020-10-01 00:00:00’
10.创建触发器
例子:构造一个触发器audit_log,在向employees_test表中插入一条数据的时候,触发插入相关的数据到audit中。
create trigger audit_log
after insert on employees_test
for each row
begin
insert into audit values(new.id,new.name);
end
在MySQL中,创建触发器语法如下:
CREATE TRIGGER trigger_name
trigger_time trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:标识触发器名称,用户自行指定;
trigger_time:标识触发时机,取值为 BEFORE 或 AFTER;
trigger_event:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
tbl_name:标识建立触发器的表名,即在哪张表上建立触发器;
trigger_stmt:触发器程序体,可以是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句,每条语句结束要分号结尾。
【NEW 与 OLD 详解】
MySQL 中定义了 NEW 和 OLD,用来表示
触发器的所在表中,触发了触发器的那一行数据。
具体地:
在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;
在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;
使用方法: NEW.columnName (columnName 为相应数据表某一列名)
11.删除,更新table
1)删除:delete table tablename
2)更新:
- 普通形式:update tablename set columnName=value where columnName=value,如果要更新多列用逗号隔开,如set to_date=NULL,from_date=‘2001-01-01’
- 可以直接在更新表的基础上使用join:
update salaries s join emp_bonus e on s.emp_no=e.emp_no
set salary = salary*1.1
where to_date = “9999-01-01”;
12.limit
1)取倒数第三个数
跳过两条取一条数据:limit 2,1 = limit 1 offset 2
2)分页
每页显示n条记录,要显示第i页数据,则可以用 limit n*(i-1),n