MySQL實戰技能包

1. 表字段按照漢字拼音排序

命令:html

若庫表爲uft8字符集時,需轉換爲gbk編碼再排序:【比較常見】
order by convert(columnname(排序的列名) using gbk) asc;
order by convert(columnname(排序的列名) using gbk) desc;

若庫表爲gbk字符集時,直接排序:
order by columnname(排序的列名) asc;
order by columnname(排序的列名) desc;
複製代碼

舉例:mysql

對數據庫user表的name字段按照漢字拼音排序,user表數據以下: sql

user表

查看user表的DDL:user表採用utf8字符集,中文不能按照拼音排序,需轉換爲gbk編碼,再進行排序 數據庫

user DDL

對user表的name字段進行gbk編碼再排序:【升序的話,英文排在中文前面的;反之降序排在後面】 bash

name asc
name desc

2. 查詢表中重複記錄/查詢表中某字段值存在重複值

通常不存在表中有徹底重複的記錄,由於咱們在設計數據庫表時,都有主鍵(id),不可重複,因此常見狀況都是表中某字段值存在重複。函數

<1> 查詢某一字段存在重複值的命令:優化

舉例:查詢user表中name字段重複值ui

方式一:使用group by和having 【簡潔,高效,推薦】編碼

命令格式:select columnname(字段名), count(*) as count from tablename(數據庫表名) group by columnname(字段名) having count > 1;
具體命令:
select name from user group by name having count(name) > 1;
或
select name, count(*) as count from user group by name having count > 1;
或
select name, count(name) as count from user group by name having count > 1 order by count desc;
複製代碼

name字段存在重複值
name字段存在重複值命令擴展

方式二:使用group by和臨時表spa

命令:select name from (select name, count(name) as count from user group by name) as usertemp where count > 1;
複製代碼

group by+臨時表

<2> 查詢多個字段同時存在重複值的命令:

舉例:查詢user表中name和address字段同時存在重複值

命令格式:

select columnname1(字段名1), columnname2(字段名2), count(*) as count from tablename(數據庫表名) group by columnname1(字段名1), columnname2(字段名2) having count > 1;
複製代碼

name,address字段值都重複

<3> 查詢某一字段存在重複值的具體行記錄信息:

方式一:使用in + 子查詢 【數據量大時,耗時長,效率低】

舉例:先用子查詢查出user表中name字段的重複值,而後在user全表中作in匹配。

name字段值重複的具體行記錄

方式二:使用臨時表作關聯查詢 【創建臨時表,耗時短,效率高,推薦】

舉例:把user表中重複的name字段值存放臨時表usertemp中,使用關聯查詢,查出重複name字段的具體行記錄信息。

臨時表關聯查詢字段重複值行記錄
說明: using() 括號必須有,關聯查詢 join using() 代表要關聯的兩個表user和usertemp,關聯的字段名是一致的,都爲name。

<4> 查詢多個字段同時存在重複值的具體行記錄信息:

舉例:

name,address字段值都重複的具體行記錄

3. 去除表中重複記錄

表中重複記錄: 指的是表中徹底重複的記錄,即全部字段值均重複。

通常咱們在設計數據庫表時,都有主鍵id,不可重複,因此通常不存在表中記錄徹底重複的狀況;若出現了此狀況,建議先從表結構設計上查找問題,增長主鍵,優化表結構。

查詢表中徹底重複的記錄命令:【不經常使用】

select distinct * from tablename(數據庫表名);
複製代碼

4. 查詢第N高薪水

思路:先按薪水字段降序排序,同時去掉重複項,結合limit,便可查出。

舉例:user表信息

user表信息

從user表中找出薪水第三高的用戶信息

降序+去重+limit

關於limit的坑提醒: 查詢user表中薪水第三高的用戶信息,以下寫sql,能夠嗎?

select distinct salary, user.* from user order by salary desc limit 3-1,1;
select distinct salary, user.* from user order by salary desc limit (3-1),1;
複製代碼

固然不能夠,limit不支持計算表達式,帶不帶括號都不行,以下報錯:

limit不支持計算表達式

總結:查詢第N高 = 降序(desc) + 去重(distinct) + limit(不含計算表達式)


擴展:查詢第N高薪水,若是不存在,返回null。

思路:先查出第N高薪水,使用ifnull函數作判斷顯示。

舉例:

ifnull+降序+去重+limit

5. 查詢涉及取餘運算MOD(x,y)

MOD(x,y):返回x除以y後的餘數。

select mod(5,2); -- 返回1
複製代碼

菜鳥教程中有MySQL相關函數的整理介紹,地址:www.runoob.com/mysql/mysql…

實際應用舉例:從user表中查出全部id爲奇數的男性的用戶信息,且按照薪資從高到低排名。

mod函數

6. 交換值

實際應用:user表中,更新操做,將男性(m)和女性(f)的性別進行交換。

update user set sex = if(sex='f','m','f');
或者
UPDATE user SET sex = (CASE sex WHEN 'm' THEN 'f' ELSE 'm' END); (爲了區分字段,關鍵字大寫)
複製代碼

交換值

7. 交換相鄰行的值

實際應用:user表中,交換相鄰兩行的用戶信息,若user表中用戶總數爲奇數的話,最後一行用戶信息不變。

解題思路:交換相鄰兩行數據能夠轉換爲交換相鄰兩行id,而後按照id排序便可。

select (
    case when mod(id,2)=1 and id = (select max(id) from user) then id 
         when mod(id,2)=1 then id+1 else id-1 
         end
) as id, name, sex, age, phone, address, salary, create_time, update_time from user order by id;
複製代碼

交換相鄰行的值

8. 相隔幾天DATEDIFF(d1,d2)

DATEDIFF(d1,d2):返回d1 -> d2之間相隔的天數

select DATEDIFF('2001-01-01','2001-02-02'); --  -32
複製代碼

實際應用:有一溫度表weather記錄着天天的平均溫度,查出後一天比前一天溫度高的日期。

溫度表:

weather表

後一天比前一天溫度高的日期:

select w1.date from weather w1 inner join weather w2 on DATEDIFF(w1.date, w2.date) = 1 and w1.temperature > w2.temperature;
複製代碼

後一天比前一天溫度高的日期

9.MySQL鏈接

分爲三類:

<1> inner join 內鏈接或等值鏈接

等價寫法:
inner join <==> join
select * from a inner join b where a.id = b.id <==> select * from a, b where a.id = b.id;
複製代碼

inner join a>b
inner join a<b

<2> left join 左鏈接

left join

<3> right join 右鏈接

right join


後續持續更新中...

相關文章
相關標籤/搜索