一、數據庫概念
1.1 DB
database:存儲數據的“倉庫”,他保存了一系列有組織的數據。一張張數據表table,存儲在DB中;
1.2 DBMS
database management system:數據庫管理系統,數據庫是通過DBMS創建和操作的容器,例如mysql、sqlserver、Oracle等安裝的軟件系統;
1.3 SQL
結構化查詢語言:專門用來與數據庫通信的語言;
二、mysql常見的命令
2.1 查看當前所有的數據庫
show databases
顯示了test1下的所有數據庫
2.2 打開指定的庫
use database庫名(具體的數據庫名字)
則當前工作數據庫直接切換到到了database下,再執行這個數據庫下不存在的表,會提示doesn't exist
2.3 查看指定庫的所有表
show tables from database庫名
2.4 查看當前庫的所有表
show tales
2.5 創建表
2.5.1 查看mysql 版本
select version()
2.5.2 不指定字符集創建表語法
字符集是Character set
①字符編碼方式是用一個或多個字節表示字符集中的一個字符
②每種字符集都有自己特有的編碼方式,因此同一個字符,在不同字符集的編碼方式下,會產生不同的二進制
常見字符集:
ASCII字符集:基於羅馬字母表的一套字符集,它采用1個字節的低7位表示字符,高位始終為0。
LATIN1字符集:相對於ASCII字符集做了擴展,仍然使用一個字節表示字符,但啟用了高位,擴展了字符集的表示范圍。
GBK字符集:支持中文,字符有一字節編碼和兩字節編碼方式。
UTF8字符集:Unicode字符集的一種,是計算機科學領域里的一項業界標准,支持了所有國家的文字字符,utf8采用1-4個字節表示字符。
不指定字符集創建表案例:
create table table_name表名(
column_name1字段名 data_type(size)字段類型及數據長度,
column_name2字段名 data_type(size)字段類型及數據長度,
column_name3字段名 data_type(size)字段類型及數據長度,
...
);
data_type數據類型:
數據類型(data_type)規定了列可容納何種數據類型。下面的表格包含了SQL中最常用的數據類型:
字節與字符:
- ASCII 碼中,一個英文字母(不分大小寫)為一個字節,一個中文漢字為兩個字節。
- UTF-8 編碼中,一個英文字為一個字節,一個中文為三個字節。新的utf8mb4字符集中一個漢字占4個字節.
- Unicode 編碼中,一個英文為一個字節,一個中文為兩個字節。
- 符號:英文標點為一個字節,中文標點為兩個字節。例如:英文句號 . 占1個字節的大小,中文句號 。占2個字節的大小。
- UTF-16 編碼中,一個英文字母字符或一個漢字字符存儲都需要 2 個字節(Unicode 擴展區的一些漢字存儲需要 4 個字節)。
- UTF-32 編碼中,世界上任何字符的存儲都需要 4 個字節。
數據類型 | 描述 |
tinyint integer(size) smallint int(size) smallint(size) tinyint(size) |
僅容納整數。在括號內規定數字的最大位數 1.tinyint: 一個字節 取值范圍 -128~127相當於java中的byte 2.smallint=integer: 兩個字節 取值范圍 -32768~32767相當於java中的short 3.mediumint:三個字節 4.int: 四個字節 取值范圍 -2147483648~2147483647 5.bigint: 8個字節相當於java的long |
decimal(size,d) numeric(size,d) |
容納帶有小數的數字。 "size" 規定數字的最大位數。"d" 規定小數點右側的最大位數。 |
char(size) | mysql5.0版本以上,varchar(20),指的是20字符,無論存放的是數字、字母還是UTF8漢字(每個漢字3字節),都可以存放20個,最大大小是65532字節 即65532/3個漢字 |
varchar(size) | 保存固定長度的字符串(可包含字母、數字以及特殊字符)。在括號中指定字符串的長度。最多 255 個字符。 注釋:如果值的長度大於 255,則被轉換為 TEXT 類型。 text:存放最大長度為 65,535 個字節的字符串。 |
date(yyyymmdd) | 容納日期。 |
2.5.2.1 查看建表語句
字符集是默認的,通過show create table 表名查看建表語句
2.5.3 創建表也可以指定字符集格式
create table table_name表名(
column_name1字段名 data_type(size)字段類型及數據長度 character set utf8 not null,
column_name2字段名 data_type(size)字段類型及數據長度character set utf8 not null,
column_name3字段名 data_type(size)字段類型及數據長度character set utf8 not null,
...
);
2.5.4 表的修改
修改列名稱
ALTER TABLE <表名> CHANGE <舊字段名> <新字段名> <新數據類型>
ALTER TABLE table_test_0512 CHANGE column_name3 column_name3_new VARCHAR(255) NOT null ;
修改表名:
ALTER TABLE <表名> rename to 新表名;
列 新增/變更數據類型:
ALTER TABLE <表名> add/modify COLUMN 字段名 數據類型(vachar/int/double) ;
列 刪除:
ALTER TABLE <表名> drop COLUMN 字段名;
修改列名:
ALTER TABLE <表名> change COLUMN 字段名 舊字段名 新字段名;
2.5.5 刪除表
如果存在再刪除,但是if exists不適用於列
DROP table IF EXISTS 表名
2.5.6 復制表
復制表的結構:
create table table_test_0513_copy like table_test_0513
查看表數據是空的
查看表結構
復制表數據
insert into table_test_0512_copy--要求表必須存在
select * from table_test_0512
2.6 創建數據庫
2.6.1 方式一
create database database庫名
2.6.2 方式二
嚴謹一點的語法是:如果不存在就創建 if not exists固定用法
create database books if not exists books;
2.6.3 庫的修改
數據層面的修改是update
庫表層的修改:
alter/rename
庫名的修改:
語法:
rename database 庫名 to 新庫名;
庫的字符集修改:character set
alter database 庫名 character set 字符集類型(utf8/gbk);
庫的刪除:
drop database 庫名;
2.7 查看表結構
desc tablename表名
int最大長度是11位。即11為字符長度,如果在建表時不指定字段int類型的長度時,系統則默認生成長度為11的字段。11也是int類型的最大長度,其中第一位表示符號+或者-,后面十位表示數字。
從 -2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647) 的整型數據(所有數字)。存儲大小為 4 個字節。
2.8 創建索引
索引被創建於已有的表中,它可使對行的定位更快速更有效。可以在表格的一個或者多個列上創建索引,每個索引都會被起個名字。用戶無法看到索引,它們只能被用來加速查詢。
注釋:更新一個包含索引的表需要比更新一個沒有索引的表更多的時間,這是由於索引本身也需要更新。因此,理想的做法是僅僅在常常用於搜索的列上面創建索引。
索引是查詢優化最主要的方式;
查詢方式:
一種是:全表掃描,即從第一行,一行行查,直到查到對應的那行才停止;
一種是:利用數據表上建立的索引進行掃描。
索引會單獨形成一張數據表,里面存儲了索引字段名、value值、指針;
這個指針是每一行value值在庫表中對應的行地址,只要通過查詢索引表知道這行數據的指針,mysql就可以直接到庫表中定位到該行並返回該行所有數據;
Mysql索引根據用途分為:
1.普通索引:列值可以取空值或重復值。創建使用關鍵字INDEX或KEY;
2.唯一索引:列值不能重復;即索引列值必須是唯一的,但可以是空值;創建使用關鍵字UNIQUE;
3.主鍵索引:主鍵索引是系統自動創建的主鍵索引,並且是唯一的。與唯一索引區別是;列值不能為空;
4.聚簇索引:就是數據存儲的物理存儲順序,非聚簇索引就是索引順序與數據的物理順序無關。一個表只能有一個聚簇索引。目前只有InoDB和solidDB支持。
5.全文索引:只能創建在varchar或text的列上;建立全文索引能夠在全文索引的列上進行查找。
(1)單列索引:就是一個索引只包含表中的一個列;比創建一個學號ID的索引;以name再創建一個姓名的單列索引。即每個索引包含一個列。
(2)組合索引(復合索引或多列索引):就是表中的兩個列或多個列來創建成一個索引;比如;以用戶ID、用戶名Name、用戶年齡Age來創建的索引就是聯合索引。
2.8.1唯一的索引 (Unique Index)
在表格上面創建某個一個唯一的索引。唯一的索引意味着兩個行不能擁有相同的索引值。
CREATE UNIQUE INDEX 索引名稱 ON 表名稱 (列名稱)
因為查了數據庫的字符集類型,編碼格式是utf8mb4一個中文是4個字節,所以767個字節最多存儲191個中文字符
TEXT、VARCHAR、CHAR等類型的列,只能用前面的 191 個字符做索引,因為 191×4=764,192×4=768,191個字符正好沒有超過 767 字節的限制。如果 char、varchar 等定義的長度超過了 191,而指定索引時未說明索引長度,則會自動使用前191個字符做索引。
但是,若是唯一索引,單列的長度不能超過 191個字符,否則報錯。
2.8.2 更新字段數據類型
ALTER TABLE <表名> MODIFY <新字段名> <新數據類型>
ALTER TABLE table_test_0512 MODIFY id varchar(191)
2.8.3 更新數據類型長度后查看索引
2.8.4 創建簡單索引
CREATE INDEX 索引名稱
ON 表名稱 (列名稱)
create index column_name1_index
on table_test_0512 (column_name1)
多個簡單索引,字段用逗號分隔即可;
2.8.5 創建表時指定主鍵和索引
2.8.5.1 不帶主鍵
CREATE TABLE `table_test_0513` (
`id` varchar(191) DEFAULT 1,
`column_name1` varchar(191) DEFAULT 'qiaqia',
`column_name2` varchar(255) DEFAULT 'guanzhu',
`column_name3_new` varchar(255) NOT NULL,
`gmv` int(11) DEFAULT 100,
UNIQUE KEY `idindex` (`id`),
KEY `column_name1_index` (`column_name1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
#刪除索引 17 drop index index_n on my_test;
2.8.5.2 帶主鍵
CREATE TABLE `table_test_05132` (
`id` varchar(191) DEFAULT 1,
`column_name1` varchar(191) DEFAULT 'qiaqia',
`column_name2` varchar(255) DEFAULT 'guanzhu',
`column_name3_new` varchar(255) NOT NULL,
`gmv` int(11) DEFAULT 100,
PRIMARY KEY `idindex` (`id`),--主鍵且默認是索引,不允許為空和重復值
KEY `column_name1_index` (`column_name1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.9 查看當前數據庫的字符集
show variables like 'char%';
名詞解釋:character_set_client
:客戶端請求數據的字符集character_set_connection
:客戶機/服務器連接的字符集character_set_database
:默認數據庫的字符集,無論默認數據庫如何改變,都是這個字符集;如果沒有默認數據庫,那就使用 character_set_server指定的字符集,這個變量建議由系統自己管理,不要人為定義。character_set_filesystem
:把os上文件名轉化成此字符集,即把 character_set_client轉換character_set_filesystem, 默認binary是不做任何轉換的character_set_results
:結果集,返回給客戶端的字符集character_set_server
:數據庫服務器的默認字符集character_set_system
:系統字符集,這個值總是utf8,不需要設置。這個字符集用於數據庫對象(如表和列)的名字,也用於存儲在目錄表中的函數的名字。
以上這些參數如何起作用:
1.庫、表、列字符集的由來
①建庫時,若未明確指定字符集,則采用character_set_server指定的字符集。
②建表時,若未明確指定字符集,則采用當前庫所采用的字符集。
③新增時,修改表字段時,若未明確指定字符集,則采用當前表所采用的字符集。
2.更新、查詢涉及到得字符集變量
更新流程字符集轉換過程:character_set_client-->character_set_connection-->表字符集。
查詢流程字符集轉換過程:表字符集-->character_set_result
3.character_set_database
當前默認數據庫的字符集,比如執行use xxx后,當前數據庫變為xxx,若xxx的字符集為utf8,那么此變量值就變為utf8(供系統設置,無需人工設置)。
3 mysql的語法規范
3.1 規則
1.不區分大小寫,但是建議關鍵字大寫,表名、列名小寫
2.每條命令最好用分號結尾
3.每條命令根據需要,可以進行縮進或換行
4.注釋:
單行注釋:#
單行注釋:--
多行注釋:/* */
3.2 查詢語句
select `id` from table_test_05132
``是着重符,為了告訴sql服務器這個是一個字段,不是關鍵字
3.3 起別名
起別名的意義:便於理解、如果有查詢字段重復可以用別名區分;
3.3.1 方式一使用as
3.3.2 方式二使用空格
3.4 加號的作用
運算符的作用
3.4.1 都是純數值型
select 100+100;兩個操作數都為數值則做加減乘除法運算
3.4.2 有字符型數值
select '100'+100;其中一方為字符型,試圖將字符型數值轉成數值型;如果轉換成功則做加法運算,
如果轉換失敗則將字符型數值轉換成0:select 'john'+100;
3.4.3 有一方是null
只要有一方是null,則結果是null
select null+100;
3.5 IFNULL和COALESCE、NVL區別
3.5.1 IFNULL(參數1,參數2);
IFNULL(判斷是否不為null的參數,為null則返回第二個參數值):
第一個參數不為null則返回第一個參數的值
如果為null,則返回第二個參數值;
這個函數只適用於mysql;
3.5.2 COALESCE(參數1,參數2,參數3...)
返回參數列表中第一個不為null的參數值;
hive與mysql通用
select IFNULL(column_name1,0) from table_test_0512
select COALESCE(column_name1,0) from table_test_0512
3.5.3 NVL(參數1,參數2)
適用於數字型、字符型和日期型 , 不適用於mysql 適用於 oracle 和hive
Select NVL(null, 2)
3.6 篩選條件表達式
3.6.1 簡單條件運算符
> 、<、 =、 !=、 <>、 >=、 <=;
3.6.2 邏輯表達式
邏輯運算符:連接多個條件表達式
與:&&=and、或:||=or、非; !=not推薦用not
非舉例:
-- 查詢gmv不在200到300之間的記錄
select * from table_test_0512
where gmv<200 or gmv>300;
-- 等同於下
select * from table_test_0512
where not(gmv>=200 and gmv<=300);--gmv在200~300之間的否定則是不在這個范圍的數據記錄
3.6.3 模糊查詢
like:
一般和通配符搭配使用
通配符:
% 任意多個字符,包含0個字符
_ 任意單個字符
like 舉例:
like的通配符在前%/_xxxxx,表示前模糊即半模糊,在后表示后模糊xxxx_/%,前后都有則表示全模糊%/_xxxxx%/_;
查詢表中第三個字符是m,第六個字符是n的column_name1
select * from table_test_0512
where column_name1 like '__m__n';--只能查ccmbbn,因為后面沒有了%或者_
select * from table_test_0512
where column_name1 like '__m__n%';-可以查ccmbbn和ccmbbnll,因為最后有%任意多個字符
查詢表中第二個字符為_的column_name1
需要用到轉義字符“\”,告訴服務器斜杠后面的_是單純的下划線不是任意單個字符
select * from table_test_0512
where column_name1 like '_\_%'
轉義字符除了用斜杠\,還可以自定義,使用函數escape,escape后面的字符就是自定義的轉義字符
select * from table_test_0512
where column_name1 like '_$_%' escape '$'
between and
in
is null;
判斷為空不能用字段名=null,因為=判斷不出來nul值,所以只能用is null;
拓展:select * from table_test_0512和
select * from table_test_0512
where column_name1 like '%%';
select * from table_test_0512
where column_name1 like '%%' or column_name3_new like '%%';
相等么?
答案是:不一定,首先%%不能查字段為null,所以為null記錄查不出來,但是只要不存在null值就相等;
3.7 where后面不可用select的as別名
因為where后的條件是針對表內的字段,執行順序高於select語句,不屬於表內的字段是不認識的
3.8 order by后面可以用select的as別名
因為排序是將查詢的select結果排序,執行順序低於select的,是認別名的;
order by 排序多個字段用逗號分隔,后面都需要加上是asc/desc,asc可以省略;
3.9 length函數
字節長度函數,在utf-8數據類型下一個英文字母是一個字節,一個中文是3個字節
在utf-8mb4是一個英文是1一個字節,一個中文是4個字節;
3.10 upper、lower
upper是字符串轉大寫
lower是字符串轉小寫
select id,column_name1,UPPER(column_name1),LOWER(column_name1) from table_test_0512
3.11 substr截取
substr(exp1,2)截取從第2個字符開始;
subatr(exp1,1,2)截取從第一個到第2個字符;
3.12 instr函數
返回字段中第一次出現的索引,如果找不到則返回0,不會返回負數
實例中找name1中m第一次出現的索引
3.13 trim函數
默認去掉前后空格
想要去掉字段前后的字符,可以傳參數:trim(exp1 from exp2)把exp2中的前后exp1去掉
3.14 lpad、rpad填充函數
lpad是左填充,如果本身字符串長度夠,就不需要填充,長度不足才要填充
參數:lpad(exp1,12,'*')
rpad 右填充
3.15 round函數
round不填保留幾位則默認是四舍五入保留整數
3.16 floor函數向下取整
3.17 ceil函數向上取整
3.18 mod函數取余
相當於%
select mod(10,3)=select 10%3
被除數是負數/正數,則余數就是負數/正數
select mod(-10,3)=-1
select mod(10,-3)=1
可以驗證下,取余就是select mod(a,b)=select a-a/b*b=select mod(-10,3)=select -10-(-10/3*3)
=select -10-(-9)=-1
3.19 日期函數
3.19.1 返回當前系統日期+時間
select now();
3.19.2 返回當前系統日期不包含時間
select curtime();
select CURRENT_DATE()
3.19.3 返回當前系統時間不包含日期
select cuttime();
3.19.4 獲取時間部分年、月、日、時、分、秒
select year(now())
select month(now())
獲取英文的月份:
一月:January(尖)、二月:February(飛鳥)、三月:march(馬吃)、四月:April(A與4型近)、五月:may(嫵媚)、六月:june(祝嗯-六一)、七月:july、八月:August、九月:September(蛇泡酒)、十月:October、十一月:November(no 溫度)、十二月:december(底)
3.20 str_to_date函數
將字符串類型的日期轉換成對應的日期格式
轉換的日期格式必須和字符串的格式一 一對應
Y是指四位年、y是兩位年、H是24小時制、h是12小時制、i是分、s是秒
不對應格式會返回null,因為要轉換的日期格式是對字符串格式解釋說明
拓展 date()函數
mysql默認支持的日期格式是YYYY-MM-DD或者YYYY/MM/DD、YYYYMMDD,所以如果字符串格式是這種可以使用date直接轉換成日期
3.21 date_format函數
如果已經得到一個標准日期格式的字段,想要自定義日期的顯示的格式,可以使用此函數
select DATE_FORMAT('2021-05-19','%Y%m%d')
拓展:from_unixtime();
將當前時間的時間戳格式轉化為標准時間格式
select from_unixtime()
3.22 日期的計算
date_add()--加
select date_add('2021-05-20',interval 10 day);
date_sub()--減
datediff(endtime,starttime)--差值
3.23 聚合函數
功能是做統計使用;
分類:sum() max() min() avg() count()
特點:
sum、avg一般作用於數值型數據
如果不是數值型會嘗試轉換,轉換數值不成功則返回0
sum() max() min() avg() count()都忽略null值
count函數一般使用count(*)來統計行數
和聚合函數一同查詢的字段必須是group by后的字段
3.24 流程控制函數
3.24.1 if函數
語法:if(判斷語句,判斷語句為true后的取值語句,判斷語句為false后的取值語句);
3.24.2 case when語法
case 要判斷的字段或表達式
when 常量1 then 要顯示的值1或語句1
when 常量2 then 要顯示的值2或語句2
。。。
else 要顯示的值n或語句n;
end as 別名--必須要起別名,因為then后面的值必須有個字段列展示出來
類似於java 的switch case
案例:
select
case user_role
when 'b' then 'b'
when 'e' then 'e'
when '全部' then '全部'
end as user_role
from rpt_operate_order_flow_period
where date_time_key=(select MAX(date_time_key)
from rpt_operate_order_flow_period)
and user_role <>'o'
group by user_role
case when 條件1 then 1
when 條件2 then 2
。。。
else 條件n then n
end as 別名
案例:
select
case
when user_role='b' then 'b'
when user_role='e' then 'e'
when user_role='全部' then '全部'
end as user_role
from rpt_operate_order_flow_period
where date_time_key=(select MAX(date_time_key)
from rpt_operate_order_flow_period)
and user_role <>'o'
group by user_role
3.24.3 case when 寫在where中的變量
同一個字段的判斷要寫在一個case中,用不同的when
案例1:
where CASE
WHEN ${datatype} ='d' and ${datadate} is null then datadate=(select current_date - integer '1')--條件判斷可以增加多個用and連接
WHEN ${datatype} ='d' and ${datadate} is not null then datadate=${datadate}
WHEN ${datatype} != 'd' then datatype = ${datatype} else true end;
但是不同的字段判斷則需要多個case
案例2:多個條件字段判斷判斷那么每一個結尾都要end結束
where period_type='accu'
and case when ${user_role} is null then user_role='全部'
else user_role in (${user_roles}) end
and case when ${user_level} is null then user_level='全部'
else user_level in (${user_levels}) end
3.24.4 case when 占位符
當字段值是隨着前端的篩選隨機變化時,那么where條件中該字段值的判斷需要用變量來表示${}
and case when ${user_role} is null then true else ${user_role} end-------${user_role}代表是字段名
and case when '${user_role}' is 'null' then true else user_role = '${user_role}' end------ '${user_role}' 代表是將false的結果復制給字段名
3.24.5 case when null is null then true
then true是表示不做處理,獲取全量數據
3.25 group by分組函數
3.25.1 group by 多個字段該怎么理解呢:
如group by name,number,我們可以把name和number 看成一個整體字段,以他們整體來進行分組的。兩個字段都相同的行會聚合成一行,否則就是多行
3.25.2 語法:
select 聚合函數,(group by后面的字段)
from 表
where
group by 分組列表
having 字段必須是聚合函數表達式,可以是表中任意字段
order by ;
案例:having的字段在group by分組內
案例:having的字段不在group by分組內
select column_name2,MAX(gmv) from table_test_0512
group by column_name2
having max(gmv)>=500
3.25.3特點:
分組查詢中的篩選條件分為兩類:
1.分組前篩選 針對的是原始數據源即where部分
2.分組后篩選 分組后的結果集having部分
group by和having、order by 后可以跟select 別名
3.35.4 group by和grouping sets
代表把group by后面的字段再次分別進行分組聚合,然后union all
比如按照月,日分組后執行grouping sets就是:
按照月分組,日=null,按照月進行聚合再union all 月=null,按照日聚合
3.26 多表關聯查詢
3.26.1 笛卡爾乘積
格式:select * from 表1,表2
表1 m行 表2 n行,結果為m*n行
發生原因是因為沒有:沒有有效的連接條件
如何避免:添加有效的連接條件即where條件;
案例:table_test_0512 10行記錄儀 table_test_0513 2條記錄,笛卡爾乘積后20條記錄;
案例:添加有效的連接條件后,2條記錄
where 條件中用:表名.字段名=表名.字段名
3.26.2 【inner】 join 連接
語法:
select 查詢列表
from 表1 別名 【連接類型】
join 表2 別名
on 連接條件
【where】
【group by】
【having】
【order by】
連接類型分類:
內連接:inner 取交集,inner可以省略的
等值連接:
如圖 on字段相等的數據記錄,不相等的行剔除
拓展1:3個及以上的表join原理
如果是三個及以上的表連接如下:那么就有順序要求,因為A和B join后的結果集和C再去連接的,所以必須前面的結果集能和C有關聯到的字段才行;
select * from A
inner join B on A.id=B.id
inner join C on A.key=C.key
非等值連接:on字段是一個非=號
a.id<=b.id則是將a表每一行的id值和b表對比,如果滿足條件則輸出展示
a的id=1 b表的id=1相等,則輸出
a的id=1小於 b表的id=2,則輸出
a的id=2 b表的id=2相等,則輸出
忽略id=10,因為是字符串沒比較出來;
自連接:自己和自己join
3.26.3 外連接
左外:left【outer】
右外:right【outer】
全外:full【outer】
3.26.3 交叉連接:cross
也就是笛卡爾乘積
3.27 子查詢
3.27.1 exists(相關子查詢)
語法:
exists(完整的查詢語句)
結果:1/0
如果子查詢結果有數據,則存在=1,否則=0
經常用來放在where后面,必須where exists子查詢存在,那么where前的查詢才生效
3.28 分頁查詢
limit offset,size
offset是起始索引,即從第幾行開始,mysql中從0開始表示第一行記錄
size是獲取條目
前5條等同於limit 5,offset=0可以省略
從2行開始,取5行
3.29 聯合查詢union
UNION 操作符用於合並兩個或多個 SELECT 語句的結果集。
UNION 內部的 SELECT 語句必須擁有相同數量的列;
列也必須擁有相似的數據類型;
每條 SELECT 語句中的列的順序必須相同;
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
注釋:
默認地,UNION 操作符選取不同的值。如果允許重復的值,請使用 UNION ALL。
UNION ALL 命令和 UNION 命令幾乎是等效的,不過 UNION ALL 命令會列出所有的值。
3.30 insert into 方式
3.30.1 insert into 表名 列名(可是部分/全部,但前提是必填項)values(和列名數據類型要一致)
3.30.2 insert into 表名 set 后面是字段名=字段值,逗號分隔多個
3.20.3 insert into select 批量插入自增id字段
#批量插入帶有自增字段的記錄
insert into rpt_kpi_dboard_1d
set @id=0;--初始化id
select (@id:=@id+1) id
3.31 update多表關聯的記錄
語法:
update 表名1 別名
inner/left/right/full join 表名2 別名
on 連接條件
set 列=值。。。
where 篩選條件
案例:
update table_test_0512 a
join table_test_0513 b
on a.id=b.id
set b.column_name3_new='update-new'--在where條件后執行set語句,只修改id=2的記錄
where b.id=2
3.32 delete數據
3.32.1 多表刪除
語法:delete 表1別名,表2別名
from 表1 別名
關聯類型 join 表2 別名
on 連接條件
where 篩選條件后刪除;
案例:
delete a,b -- 要刪除的表記錄,刪除a,b表id=2的記錄
from table_test_0512 a
join table_test_0513 b
on a.id=b.id-- 前面這一串是獲得多表關聯的結果集
where b.id=2
3.32.2 單表刪除
delete from users where 條件語句
3.33 truncate 數據
語法
truncate table 表名;
案例:
truncate table users;--truncate語法是不能加where條件,要刪除都是整個表刪除;
3.34 to_char(數據,FM999990.09) 格式化函數-oracle sql
select to_char(0.63,'FM999,999,990.00' )
其中 9 代表 如果該位存在數字則顯示數字,不存在顯示空格,其中 FM 代表 如果是因為9 帶來的空格則刪除因為該為沒有數據
其中 0 代表 如果存在數字則顯示數字,不存在則顯示0, 即占位符,為了解決小數展示.001,沒有展示個位0
3.35 row_number()排序和rank()區別
3.35.1row_number
row_number只是分組后按照字段進行排序后,給一個序號,即便記錄一模一樣也會有一個先后順序,
row_number() over(PARTITION BY coalesce(t1.data_date,t2.data_date) ORDER BY t1.sales_amt desc ) as sales_amt_rank
如果t1和t2表取並集后,t1表對應的datadate字段有的行是null,那么為null的作為一個分組進行123的排序,不為null的相同value結果的作為一組進行123的排序
但是如果排序字段取t1和t2的datadate就不存在為null的情況,都會有具體的日期了,就不會存在相同日期有多個一樣的排名了
3.35.2 rank
RANK()函數,顧名思義排名函數,可以對某一個字段進行排名,這里為什么和ROW_NUMBER()不一樣那,ROW_NUMBER()是排序,當存在相同排序值時,ROW_NUMBER()會依次進行排序,他們序號不相同,而Rank()則不一樣,出現相同的,他們的排名會是一樣的值。
3.36 next_day(sysdate,'mo') -oracle
sysdate查詢出下一個星期一是哪一日
dt between to_char(dateadd(to_date1(next_day(to_char(to_date1('${bizdate}','yyyymmdd'),"yyyy-mm-dd"), "MO"),"yyyy-mm-dd"),-7,'dd'),"yyyymmdd") and '${bizdate}'
其中 next_day(to_char(to_date1('${bizdate}','yyyymmdd'),"yyyy-mm-dd"), "MO")是下一個星期一是哪一天
3.37 取最近一小時內每五分鍾的合計數據
DATE_FORMAT(
concat(
date( pay_time ),-- 獲取支付時間的年-月-日
' ',-- 和空格拼接
HOUR ( pay_time ),-- 獲取支付時間的h
':',-- 和空格拼接
cast( floor( MINUTE ( pay_time ) / 5 ) * 5 AS INT ),-- 獲取支付時間中整5分鍾數的分鍾
':00'
),
'%Y-%m-%d %H:%i:%s' --指定拼接后的日期格式
);
3.38 返回7天內數據平均值
select avg(data_num) (SELECT
data_dt,
sum( data_num ) as data_num -- 7日平均數
FROM
rpt_ubt_realtime_repost_d_15m
WHERE
data_dt BETWEEN DATE_SUB( CURDATE(), INTERVAL 6 DAY ) -- 從當前日期-6天+當天=7天
AND CURDATE()
AND data_hour LIKE '%09:15:00'
AND data_type IN ( 'effective_repost', 'confirm', 'request' )
AND channel_type = 'ALL'
group by data_dt--每一天的數據匯總
)
3.39 with as
當一條SQL語句,在同一個SQL語句中多次出現時,可以使用with as 將該SQL語句作為公用SQL,之后,在下一條SQL中,使用公用SQL語句。
使用:如下
with tt as (select * from table_1);
select * from tt; -- tt代表的是公用SQL
公共語句和引用語句之間不能有;執行時要一起選中
with tt as (select NOW()) select * from tt;
3.40 sum() over (order by )--oracle
3.40.1 sql 時間類型:
date:yyyy-mm-dd
time:hh:mi:ss
datetime:yyyy-mm--dd hh:mi:ss
timestamp:10位時間戳
year:yyyy
先sum,然后按照paytime正序排列
SELECT
pay_time AS time,
sum( pay_amount )over ( ORDER BY pay_time ) AS yesterday_money
3.41 first_value() over(partition by rder by)-oracle
分組排序后取第一個值
select first_value(cur_gmv) over
(partition by data_date order by data_time desc) cur_gmv
from datahub_mysql_rpt_trd_channel_1s_his
where channel='大盤'
3.42 map類型的字段插入方式
只能用insert into select的方式,且必須全量所有字段一起同時插入才行
INSERT INTO akdc.stg_trfc_event_mshop_wx_app_15m_test
PARTITION(dt='20201126',mi='1000')--指定分區
select '1606199447' as xwhen,--時間
map('$debug','0','coupon_amount','20') as xcontext--map類型
,'49db5d52c1480201' as appid,
'0CO5jlZThG' as xwho,
'share' as xwhat;
3.43 插入分區values
INSERT INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2,...)][(co1name1,colname2,...)]
[VALUES (col1_value,col2_value,...),(col1_value,col2_value,...),...]
參數說明:
- tablename:待插入數據的表名稱。該表為已經存在的表。
- PARTITION (partcol1=val1, partcol2=val2,...)]:分區信息。如果需要更新的表為分區表,您需要指定該參數。
- [(co1name1,colname2,...):目標表中的字段名稱。
- col_value:目標表中列對應的列值。多個列值之間用逗號(,)分隔。該列值必須為常量,未指定列值時,默認值為NULL。
INSERT INTO TABLE PARTITION (分區字段)(目標表列)values()
3.44 replace函數
語法:
replace(字段,被替換數據,要替換的數據)
3.45 ADDTIME
SELECT ADDTIME('2018-10-31 23:59:59','0:1:1')
3.46 convert(decimal(18,2),price)---sqlserver
select convert(decimal(18,2),1343.546567) 結果:1343.55
decimal(18,0)
18是定點精度,0是小數位數。
decimal(a,b)
a指定指定小數點左邊和右邊可以存儲的十進制數字的最大個數,最大精度38。
b指定小數點右邊可以存儲的十進制數字的最大個數。小數位數必須是從 0 到 a之間的值。默認小數位數是 0。
3.47 unoin all
unoin all 以上的sql是語句作為一個整體子級
如:select * from
(select * from aa)p1
unoin all
(select * from aa)p2
結果不會查出來p1和p2並集,而是把
select * from
(select * from aa)p1作為一個子級和(select * from aa)p2做並集
這里的select * from 是和p1是一體的
3.48 least(num1,num2)
那個數值小,取哪個
least(tt2.virtual_real_amt,tt2.real_amt*0.10)
4 事務的概念
事務是由單獨單元的一個或多個sql語句組成,在這個單元中(執行sql時選中的所有語句),每個mysql語句是相互依賴的。而整個單獨單元作為一個不可分隔的整體,如果單元中某條sql語句一旦執行失敗或者產生錯誤,整個單元將會回滾;
5 視圖的概念
從5.0.1版本開始提供視圖的功能。一種虛擬存在的表,行和列的數據來自定義視圖的邏輯sql里的表,並且是在使用視圖時動態生成,只保存sql邏輯,不保存查詢結果;
5.1創建視圖
語法:
/*
create view 視圖名
as
select from表
*/
create view table_test_0512_view as
select * from table_test_0512
where id=10
在視圖列表就會看到創建的視圖
5.2 查看視圖和查看普通表是一樣的
5.3 刪除視圖
drop view 視圖名
6 用戶自定義變量
語法:
set @變量=變量值;或者
set @變量:=變量值;
用戶自定義變量和引用的語句要用分號隔開,否則屬於一個事務同時執行,那么后面的語句拿不到初始化后的值會爆錯;
set @id=2;--限執行這個
insert into table_test_0513--再執行這個,那么第二次就不會執行初始化語句了,就會不斷地自增下去的;
values(@id:=@id+1 ,'pipei1','pipei1','pipei1',2)