mysql知識點回顧與梳理

1、sql語句執行順序git

  1. from
  2. join
  3. on
  4. where
  5. group by
  6. avg,sum,count等各類函數
  7. having
  8. select
  9. distinct
  10. order by(asc(升序),desc(降序))
  11. limit

2、如何獲取表記錄,或者某字段不一樣值個數sql

select 數據庫

count(distinct a.user_id) as cntexpress

from table a函數

3、如何在sql表(假設爲表a)中刪除重複行編碼

方法1:url

stp1:篩選出不重複的表記錄spa

        select distinct a.* from a.net

stp2:將記錄插入到臨時表b中blog

        insert into b

        select distinct a.* from a

stp3:清空表a 

       truncate table a

stp4:將臨時表數據插入表a

       insert into a

       select * from b

方法2:

delete from  a
where (a.col_1,a.col_2) in

( select col_1,col_2 

   from a

   group by col_1,col_2

   having count(*) > 1)

and rowid not in (select min(rowid) a vitae group by col_1,col_2 having count(*)>1)

4、My Sql row_number...partition_by函數以及如何模擬它

SELECT collect_user_name, collect_time,rank
FROM
(
SELECT t.collect_user_name,t.collect_time,
CASE WHEN @partition_by =null  or  @partition_by!= t.collect_user_name THEN @rownum := 1
ELSE @rownum :=@rownum + 1
END AS rank
,@partition_by := t.collect_user_name  AS  partition_by
FROM (select @partition_by:=null, @rownum:=0)s, (
SELECT collect_user_name, collect_time FROM pl_collect_call_info cat
WHERE date(cat.collect_time) = curdate()
ORDER BY cat.collect_user_name,cat.collect_time
) t

#INNER JOIN (SELECT @rownum :=0) r ON 1=1
#INNER JOIN (SELECT @partition_by :='') p ON 1=1
#ORDER BY t.collect_user_name, t.collect_time
)tb ;

5、My SQL間隔進行日期和時間算術,以及示例

日期間比較:date(regist_time)>=curdate() - interval 2 day

日期間計算:datediff(a,b):返回a,b相隔天數; adddate(a,n):a加上n天;subdate(a,n):a減去n天;

返回當前時間:curtime(),current_time();

返回當前日期和時間:now(), current_timestamp(), localtime(), localtimestamp(), sysdate()

 

日期和時間格式

年月日:DATE_FORMAT(cld.calendar_date, '%Y%m%d')

時分秒:DATE_FORMAT(NOW(),'%H:%i:%s'), H :24小時格式;h:12小時格式。

年月日&時分秒:DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s')

 

時間差函數:

datediff函數,返回值是相差的天數,不能定位到小時、分鐘和秒。

-- 相差2天(a-b)
select datediff('2018-03-22 09:00:00', '2018-03-20 07:00:00');

 

 TIMEDIFF函數,按時間格式返回時間差,含時分秒。語法:timediff(a,b):返回兩個時間相減獲得的差值,(a-b)

SELECT timediff('2018-05-21 14:51:43','2018-05-19 12:54:43');

  TIMESTAMPDIFF函數,有參數設置,能夠具體精確到天(DAY)、小時(HOUR),分鐘(MINUTE)和秒(SECOND),使用起來比datediff函數更加靈活。對於比較的兩個時間,時間小的放在前面,時間大的放在後面。(b-a)

--相差1天
select TIMESTAMPDIFF(DAY, '2018-03-20 23:59:00', '2015-03-22 00:00:00');

 

--相差49小時

select TIMESTAMPDIFF(HOUR, '2018-03-20 09:00:00', '2018-03-22 10:00:00');

  

--相差2940分鐘
select TIMESTAMPDIFF(MINUTE, '2018-03-20 09:00:00', '2018-03-22 10:00:00');

 

--相差176400秒

select TIMESTAMPDIFF(SECOND, '2018-03-20 09:00:00', '2018-03-22 10:00:00');

 6、My SQL使用null,及處理null

注意:空值不佔空間,null值佔空間。定義爲NOT NULL的字段只能插入空值,不能插入null值,而NULL字段能夠插入空值,也能夠插入null值。

能夠發現 is not null 只會過濾爲null值的列,而<>會同時過濾空值和null值,因此要根據實際狀況選擇過濾方式。另外,判斷null值只能用 is null 或 is not null ,不能用 = 或 <>。

注意事項: 

1:在進行count()統計某列的記錄數的時候,若是採用的NULL值,會別系統自動忽略掉,可是空值是會進行統計到其中的。

2: 判斷NULL 用IS NULL 或者 is not null,SQL 語句函數中可使用ifnull()函數來進行處理,判斷空字符用 =」或者 <>」來進行處理 。

3: 對於MySQL特殊的注意事項,對於timestamp數據類型,若是往這個數據類型插入的列插入NULL值,則出現的值是當前系統時間。插入空值,則會出現 ‘0000-00-00 00:00:00’ 。

4:對於空值的判斷究竟是使用is null 仍是 =」要根據實際業務來進行區分。

五、當使用ORDER BY時,首先呈現NULL值。若是你用DESC以降序排序,NULL值最後顯示。當使用GROUP BY時,全部的NULL值被認爲是相等的,故只顯示一行。

相關函數:

 COALESCE(exp1,value1,...)函數:返回第一個非null值,若是全部都爲null,則返回null;

IFNULL(expression,value) 函數:若是表達式爲null,則返回value,不然返回表達式的值;

7、使用MySQL會話變量實現窗口函數

      函數形式:聚合函數() over (partition by ... order by ...) ,其中over() 爲窗口 ;

      窗口分類:可分爲靜態窗口、滑動窗口(聚合函數)。     

     按照功能劃分,能夠把MySQL支持的窗口函數分爲以下幾類:

  • 序號函數:row_number() / rank() / dense_rank()
  • 分佈函數:percent_rank() / cume_dist()
  • 先後函數:lag() / lead()
  • 頭尾函數:first_val() / last_val()
  • 其餘函數:nth_value() / nfile()

詳細可參考隨筆:使用MySQL會話變量實現窗口函數

對於滑動窗口的範圍指定,有兩種方式,基於行和基於範圍,具體區別以下:

一、基於行:

一般使用BETWEEN frame_start AND frame_end語法來表示行範圍,frame_start和frame_end能夠支持以下關鍵字,來肯定不一樣的動態行記錄:

CURRENT ROW 邊界是當前行,通常和其餘範圍關鍵字一塊兒使用

UNBOUNDED PRECEDING 邊界是分區中的第一行

UNBOUNDED FOLLOWING 邊界是分區中的最後一行

expr PRECEDING 邊界是當前行減去expr的值

expr FOLLOWING 邊界是當前行加上expr的值

好比,下面都是合法的範圍:

rows BETWEEN 1 PRECEDING AND 1 FOLLOWING 窗口範圍是當前行、前一行、後一行一共三行記錄。

rows UNBOUNDED FOLLOWING 窗口範圍是當前行到分區中的最後一行。

rows BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 窗口範圍是當前分區中全部行,等同於不寫。

二、基於範圍:

和基於行相似,但有些範圍不是直接能夠用行數來表示的,好比但願窗口範圍是一週前的訂單開始,截止到當前行,則沒法使用rows來直接表示,此時就可使用範圍來表示窗口:INTERVAL 7 DAY PRECEDING。Linux中常見的最近1分鐘、5分鐘負載是一個典型的應用場景。

有的函數無論有沒有frame子句,它的窗口都是固定的,也就是前面介紹的靜態窗口,這些函數包括以下:

  • CUME_DIST()
  • DENSE_RANK()
  • LAG()
  • LEAD()
  • NTILE()
  • PERCENT_RANK()
  • RANK()
  • ROW_NUMBER()

8、時間與時間間隔的運算有哪些

 參考第五條 

9、concat(,) 與group concat()函數

concat()函數

一、功能:將多個字符串鏈接成一個字符串。

二、語法:concat(str1, str2,...)

返回結果爲鏈接參數產生的字符串,若是有任何一個參數爲null,則返回值爲null。

 

group_concat()函數

功能:將group by產生的同一個分組中的值鏈接起來,返回一個字符串結果。該函數返回帶有來自一個組的鏈接的非NULL值的字符串結果。

例如:

  

 

 

一、使用group concat()函數實現列轉行

 

二、使用substring_indexcross join將列裏面的的數字都拆分出來,把一行變成一列

substring_index(str,delim,count) 
說明:substring_index(被截取字段,關鍵字,關鍵字出現的次數) 
例:select substring_index("blog.jb51.net","。",2) as abstract from my_content_t 
結果:blog.jb51 
(注:若是關鍵字出現的次數是負數 如-2 則是從後倒數,到字符串結束)

select substring_index("blog.jb51.net",".",-2) as abstract

結果:jb51.net 

 表a cross join 表b,以b爲準,返回表b每行對應的表a中的全部記錄(表b每行都對應表a中的全部的記錄)

例如:存在下表digits,表gurl

 

 

 a cross join b,返回

 

行轉列實例:

 

 附代碼以下:

select *,substring_index(gurl, ',', digit), SUBSTRING_INDEX(substring_index(gurl, ',', digit),',' ,- 1) gurl
FROM digits
cross join gurl
where digit BETWEEN 1 AND
(SELECT 1 + LENGTH(gurl) - LENGTH(REPLACE (gurl, ',', '')));

 

 10、where、having的條件篩選類型有哪些,哪些包含null,哪些不包含

「Where」 是一個約束聲明,是在查詢結果集返回以前約束來自數據庫的數據,且Where中不能使用聚合函數
「Having」是一個過濾聲明,是在查詢結果集返回之後對查詢結果進行的過濾操做,在Having中可使用聚合函數

HAVING語句一般(親自驗證,不是必須!)與GROUP BY語句聯合使用,用來過濾由GROUP BY語句返回的記錄集。

HAVING語句的存在彌補了WHERE關鍵字不能與聚合函數聯合使用的不足

 

11、length()與char_length

select length(remerk),char_length(remerk),mad.*
from `id-admin-db`.ad_operate_log mad
limit 10;

 

 

char_length(str)
一、單位爲字符
二、無論漢字仍是數字或者是字母都算是一個字符

length(str)
一、字節,utf8編碼下,一個漢字三個字節,一個數字或字母一個字節。
二、gbk下,一個漢字兩個字節,一個數字或字母一個字節。

length()<>char_length()能夠用來檢驗是否含有中文字符

相關文章
相關標籤/搜索