1.select后對表進行修改(delete)
報錯:You can’t specify target table ‘Person’ for update in FROM clause
原因:mysql不能在同一語句中先select出同一表中的某些值,然后對這個表做修改
錯誤寫法
delete from Person
where id not in(
select min(id) id
from Person
group by email
)
解決方法:添加臨時表
正確寫法
delete from Person
where id not in(
select * from (
select min(id) id
from Person
group by email
) t1
)
2.函數(shù)GROUP_CONCAT()
我們可以使用函數(shù) GROUP_CONCAT() 將多行中的多個值組合成一個字符串。下面顯示了 GROUP_CONCAT() 函數(shù)的語法:
GROUP_CONCAT(
DISTINCT 字段 ----去重
ORDER BY 字段 ----ASC/DESC
SEPARATOR sep ---分隔符: SEPARATOR ','
);
用例
select
sell_date ,
count(distinct product) num_sold ,
group_concat(
distinct product
separator ','
) products
from
Activities
group by
sell_date
3.使用正則表達(dá)式
思路
一般來說,如果你被要求匹配一個字符串,應(yīng)該最先想到寫一個正則表達(dá)式模式進行匹配。
正則表達(dá)式提供各種功能,以下是一些相關(guān)功能:
正則表達(dá)式書寫格式 |
---|
^:表示一個字符串或行的開頭 |
[a-z]:表示一個字符范圍,匹配從 a 到 z 的任何字符。 |
[0-9]:表示一個字符范圍,匹配從 0 到 9 的任何字符。 |
[a-zA-Z]:這個變量匹配從 a 到 z 或 A 到 Z 的任何字符。請注意,你可以在方括號內(nèi)指定的字符范圍的數(shù)量沒有限制,您可以添加想要匹配的其他字符或范圍。 |
[^a-z]:這個變量匹配不在 a 到 z 范圍內(nèi)的任何字符。請注意,字符 ^ 用來否定字符范圍,它在方括號內(nèi)的含義與它的方括號外表示開始的含義不同。 |
[a-z]*:表示一個字符范圍,匹配從 a 到 z 的任何字符 0 次或多次。 |
[a-z]+:表示一個字符范圍,匹配從 a 到 z 的任何字符 1 次或多次。 |
.:匹配任意一個字符。 |
\.:表示句點字符。請注意,反斜杠用于轉(zhuǎn)義句點字符,因為句點字符在正則表達(dá)式中具有特殊含義。還要注意,在許多語言中,你需要轉(zhuǎn)義反斜杠本身,因此需要使用\.。 |
$:表示一個字符串或行的結(jié)尾。 |
例子
SELECT user_id, name, mail
FROM Users
-- 請注意,我們還轉(zhuǎn)義了`@`字符,因為它在某些正則表達(dá)式中具有特殊意義
WHERE mail REGEXP '^[a-zA-Z][a-zA-Z0-9_.-]*\\@leetcode\\.com$';
4.DATE_FORMAT()
將日期值格式化為特定格式,請使用DATE_FORMAT函數(shù)。 DATE_FORMAT函數(shù)的語法如下:
DATE_FORMAT(date,format); ---date 字段,format 需要格式
DATE_FORMAT(trans_date,'%Y-%m') ---%Y-%m 2023-08
format | date |
---|---|
%D | 英文后綴如:0th, 1st, 2nd等的一個月之中的第幾天 |
%d | 如果是1個數(shù)字(小于10),那么一個月之中的第幾天表示為加前導(dǎo)加0, 如:00, 01,02, …31 |
%H | 24小時格式的小時,前導(dǎo)加0,例如:00,01…23 |
%h | 小時,12小時格式,帶前導(dǎo)零,例如:01,02 … 12 |
%Y | 表示年份,四位數(shù),例如2000,2001 |
%y | 表示年份,兩位數(shù),例如00,01 |
%m | 具有前導(dǎo)零的月份名稱,例如:00,01,02,… 12 |
%M | 月份全名稱,例如:January, February,…December |
format | date |
---|---|
%Y-%m-%d | 2017/04/30 |
%Y-%m | 2017/04 |
5.count() 加條件
-
COUNT( state=‘a(chǎn)pproved’ OR NULL ) >需要在后面 + or null
-
COUNT( IF (state = ‘a(chǎn)pproved’, 1, NULL ) )
需要注意的是,count只有在字段數(shù)據(jù)為NULL時才不計入數(shù)量,如果IF (state = ‘a(chǎn)pproved’, 1, NULL ) 改為IF (state = ‘a(chǎn)pproved’, 1, 0 ) ,那么非 approved的數(shù)據(jù)也會被計入其中導(dǎo)致錯誤。
6.關(guān)于GROUP BY 中使用聚合函數(shù)去跟普通數(shù)據(jù)做比較而導(dǎo)致查詢結(jié)果錯誤的點
-------------- min(order_date) = customer_pref_delivery_date --------------
題目:
delivery_id 是表的主鍵。
該表保存著顧客的食物配送信息,顧客在某個日期下了訂單,并指定了一個期望的配送日期(和下單日期相同或者在那之后)。
如果顧客期望的配送日期和下單日期相同,則該訂單稱為 「即時訂單」,否則稱為「計劃訂單」。
「首次訂單」是顧客最早創(chuàng)建的訂單。我們保證一個顧客只會有一個「首次訂單」。
要求:寫一條 SQL 查詢語句獲取即時訂單在所有用戶的首次訂單中的比例。保留兩位小數(shù)。
select customer_pref_delivery_date
from Delivery
group by customer_id
having min(order_date) = customer_pref_delivery_date
這個sql執(zhí)行結(jié)果是錯誤的,因為部分?jǐn)?shù)據(jù)會被忽略掉,比如那些有多條數(shù)據(jù)的(一個customer_id可以有多條消費記錄), having min(order_date) = customer_pref_delivery_date 拿到最小的order_date后去跟這個組內(nèi)的customer_pref_delivery_date去比較,但我們不能保證它拿的是不是min(order_date) 對應(yīng)的那個customer_pref_delivery_date,所以這里的 “ = ”,即比較,是有問題的(這種情況下應(yīng)該是取組內(nèi)第一條數(shù)據(jù)的customer_pref_delivery_date去跟min(order_date) 做比較,因為98的可以取到,其他3組取不到)
以上是符合條件的,但是會被篩選掉,導(dǎo)致錯誤
如果非要這么寫,那么需要搞清楚要比較的是什么customer_pref_delivery_date,比如這里要的是最小的customer_pref_delivery_date(初步判斷,不建議這么寫)
select customer_pref_delivery_date
from Delivery
group by customer_id
having min(order_date) = min(customer_pref_delivery_date)
正確的完整寫法
select round(count(order_date=customer_pref_delivery_date or null) *100 / count(*) ,2) immediate_percentage
from Delivery
where (customer_id,order_date)
in (
select customer_id,min(order_date) order_date
from Delivery
group by customer_id
)
思路是先查詢拿到所有消費者的「首次訂單」,再拿原表去篩選并計算order_date=customer_pref_delivery_date的記錄數(shù),最后求比率
6.窗口函數(shù)(可用于部門績效排名,學(xué)校成績排名等)
<窗口函數(shù)> over (partition by <用于分組的列名>
order by <用于排序的列名>
rows/range子句<用于定義窗口大小> )
--------------------------- 案例 -----------------------------
公司的主管們感興趣的是公司每個部門中誰賺的錢最多。一個部門的 高收入者 是指一個員工的工資在該部門的 不同 工資中 排名前三 。
select t3.Department ,t3.Employee ,t3.salary
from (
select t2.name Department ,t1.name Employee ,
dense_rank() over(partition by t1.departmentId order by t1.salary desc) dr,
t1.salary
from Employee t1
left join Department t2
on t1.departmentId = t2.id
) t3
where t3.dr <=3
-------------------------------------------------------------
窗口函數(shù)>可以放以下兩種函數(shù):
1) 專用窗口函數(shù),即rank, dense_rank, row_number等。
- Rank:存在并列排名,且占用原來名次,會跳數(shù)字。
- Dense_rank: 存在并列排名,不占用原來名次,不跳數(shù)
- Row_number:不存在并列排名
成績 | Rank | Dense_rank | Row_number |
---|---|---|---|
100 | 1 | 1 | 1 |
100 | 1 | 1 | 2 |
100 | 1 | 1 | 3 |
98 | 4 | 2 | 4 |
2) 聚合函數(shù),如sum,avg,count,max,min等
group by 與 partition by 的區(qū)別
滑動窗口:rows&range用法
- ROWS: 表示按照行規(guī)定范圍,根據(jù)order by子句排序后,取的前N行及后N行的數(shù)據(jù)計算。常用:rows n preceding表示從當(dāng)前行到前n行(包括當(dāng)前行)
- RANGE:表示按照值規(guī)定范圍,根據(jù)order by子句排序后,指定當(dāng)前行對應(yīng)值的范圍取值,行數(shù)不固定,只要行值在范圍內(nèi),對應(yīng)行都包含在內(nèi)。適用于對日期、時間、數(shù)值排序分組
ROWS | 解釋 |
---|---|
Current Row | 當(dāng)前行 |
n preceding | 前 n 行,n 為數(shù)字, 比如 2 Preceding 表示前2行 |
unbounded preceding | 當(dāng)前行到分區(qū)中的開頭行 |
n following | 后n行,n 為數(shù)字, 比如 2 following 表示后2行 |
unbounded following | 當(dāng)前行到分區(qū)中的結(jié)尾行 |
rows between 1 preceding and 1 following | 窗口范圍是當(dāng)前行、前一行、后一行,共三行記錄 |
ROWS例子
select *,sum(weight) over(order by turn asc) TotalWeight
from Queue
注意:這里sum()是求 當(dāng)前行 + 當(dāng)前行前面的所有行
因為order by 后面不加 窗口范圍 則默認(rèn)查看 當(dāng)前行 + 當(dāng)前行前面的所有行,相當(dāng)于rows unbounded preceding,如圖所示文章來源:http://www.zghlxwxcb.cn/news/detail-658089.html
RANGE | 解釋 |
---|---|
range interval 6 day preceding | 最近7天的值(6天前+當(dāng)天的值) |
range between interval 1 day preceding and interval 1 day following | 前后一天和當(dāng)天的值 |
interval
/??nt?rvl/
n.間隔;(時間上的)間隙;間歇
preceding
/pr??si?d??/
v.先于;在…之前發(fā)生(或出現(xiàn));走在…前面
adj.在前的;前面的
following
/?fɑ?lo???/
adj.下列的;下述的;(時間上)接著的
n.下列;如下;下述;(統(tǒng)稱)擁護者,追隨者
v.跟隨;跟著;(指時間或順序)在…后發(fā)生,因…而發(fā)生;在…后做文章來源地址http://www.zghlxwxcb.cn/news/detail-658089.html
到了這里,關(guān)于MySQL- sql語句基礎(chǔ)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!