日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

今天就淺顯寫一篇文章專門介紹數(shù)據(jù)處理中常見的sql查詢場景中的復(fù)雜查詢。為什么單獨(dú)說復(fù)雜查詢呢?因?yàn)樵跇I(yè)務(wù)開發(fā)中我們常用orm就可以解決很多查詢問題,但是都是比較簡單的那種sql,所以orm就能滿足。但是一旦涉及到復(fù)雜的查詢,orm就束手無策了。這個(gè)時(shí)候我們一般都是寫sql查詢,但是很多sql還是不太復(fù)雜。真正復(fù)雜的sql一般都是業(yè)務(wù)上線之后,領(lǐng)導(dǎo)找你統(tǒng)計(jì)各個(gè)維度的數(shù)據(jù),那么這個(gè)時(shí)候sql能力就非常重要了,因?yàn)樗婕昂芏啾砗芏嘧侄魏芏嘧硬樵儭D菫榱艘惶炀湍苷莆諏憦?fù)雜sql的能力,為此爆肝這篇文章,一起學(xué)習(xí)成長。

一. 明確需求

返回所有國家以及相關(guān)呼叫的數(shù)量及其平均持續(xù)通話時(shí)間(以秒為單位)。在結(jié)果中,僅顯示平均呼叫持續(xù)時(shí)間大于所有呼叫的平均呼叫持續(xù)時(shí)間的國家。

1. 拆解需求

  1. 需要展示所有國家ID或者國家名稱。
  2. 相關(guān)呼叫的數(shù)量:展示國家的呼叫統(tǒng)計(jì)數(shù)量。
  3. 平均持續(xù)通話時(shí)間:展示國家的呼叫平均持續(xù)時(shí)間,單位:秒。

2. 條件

僅顯示平均呼叫持續(xù)時(shí)間大于所有呼叫的平均呼叫持續(xù)時(shí)間的國家:

那就是先計(jì)算所有呼叫的AVG(endTime-startTime),然后每個(gè)國家的平均呼叫時(shí)間與它比較即可。

3. 涉及到的表:

  1. 國家:country
  2. 呼叫:call
  3. 城市:city
  4. 用戶:customer

為什么需要city和customer表呢?因?yàn)閏all中有外鍵customer,而customer中有外鍵city,city中有外鍵country。

因?yàn)橐故舅袊遥虼艘樵僣ountry,而想統(tǒng)計(jì)呼叫,就得鏈接call,怎么能找到call呢,就得從country->city->customer->call。

黑色部分就是需要用到的表

二.開始設(shè)計(jì)查詢

1. 先寫出整體框架SQL

通過明確需求得知,我們需要關(guān)聯(lián)四張表:country,city,customer和call。

拆解需求中提到“展示所有國家的名稱”,那么這是大前提,因此如果我們想正確使用這些表,我們需要使用外鍵LEFT JOIN這些表。甚至我們現(xiàn)在不考慮最終查詢,我們就知道它將包含以下部分:

SELECT 
 ...
FROM country 
LEFT JOIN city ON city.country_id = country.id
LEFT JOIN customer ON city.id = customer.city_id
LEFT JOIN call ON call.customer_id = customer.id
...;

到這里我們必須做一件事,那就是測試這樣的查詢返回什么:

SELECT 
 *
FROM country 
LEFT JOIN city ON city.country_id = country.id
LEFT JOIN customer ON city.id = customer.city_id
LEFT JOIN call ON call.customer_id = customer.id;

這一步驟非常必要,因?yàn)槲覀兛梢钥吹綌?shù)據(jù)是什么樣子的,為后面的查詢做好基礎(chǔ)。

2. 在添磚加瓦

計(jì)算條件中的查詢:

SELECT AVG(DATEDIFF(SECOND, call.start_time, call.end_time)) FROM call

DATEDIFF函數(shù)計(jì)算開始時(shí)間和結(jié)束時(shí)間之間給定時(shí)間段(單位:秒)的單位差。

計(jì)算相關(guān)呼叫的數(shù)量:

SUM(CASE WHEN call.id IS NOT NULL THEN 1 ELSE 0 END) AS calls

SUM函數(shù)對呼叫統(tǒng)計(jì)數(shù)量。

計(jì)算平均持續(xù)通話時(shí)間:

AVG(ISNULL(DATEDIFF(SECOND, call.start_time, call.end_time),0)) AS avg_diff

這里大家可能發(fā)現(xiàn)我有對NULL做了判斷,不管是使用ISNULL函數(shù)還是IS NOT NULL判斷。為什么呢?因?yàn)?code>LEFT JOIN的時(shí)候,右邊可能出現(xiàn)NULL的情況,我們怎么知道的呢?這就是我們上面提到的:必須將整體SQL框架先打印看結(jié)果,知道數(shù)據(jù)長啥樣,自然就知道哪里需要用NULL邏輯特殊處理了

好了,現(xiàn)在可以把這些sql添加到SQL框架中了:

SELECT 
 country.country_name,
 SUM(CASE WHEN call.id IS NOT NULL THEN 1 ELSE 0 END) AS calls,
 AVG(ISNULL(DATEDIFF(SECOND, call.start_time, call.end_time),0)) AS avg_diff
FROM country 
LEFT JOIN city ON city.country_id = country.id
LEFT JOIN customer ON city.id = customer.city_id
LEFT JOIN call ON call.customer_id = customer.id
GROUP BY 
 country.id,
 country.country_name

最后一步:按照條件:“僅顯示平均呼叫持續(xù)時(shí)間大于所有呼叫的平均呼叫持續(xù)時(shí)間的國家”,我們可以很容易得出,查詢最后的結(jié)果需要用HAVING對聚合結(jié)果做下過濾,因?yàn)?ldquo;所有呼叫的平均呼叫持續(xù)時(shí)間”和“均呼叫持續(xù)時(shí)間”我們已經(jīng)統(tǒng)計(jì)出來了,因此大于長這樣:

HAVING AVG(ISNULL(DATEDIFF(SECOND, call.start_time, call.end_time),0)) > (SELECT AVG(DATEDIFF(SECOND, call.start_time, call.end_time)) FROM call)

所以最后的SQL長這樣:

--返回所有國家以及相關(guān)呼叫的數(shù)量及其平均持續(xù)通話時(shí)間(以秒為單位)。在結(jié)果中,僅顯示平均呼叫持續(xù)時(shí)間大于所有呼叫的平均呼叫持續(xù)時(shí)間的國家。
SELECT 
    country.country_name,
    SUM(CASE WHEN call.id IS NOT NULL THEN 1 ELSE 0 END) AS calls,
    AVG(ISNULL(DATEDIFF(SECOND, call.start_time, call.end_time),0)) AS avg_diff
FROM country 
-- 使用LEFT JOIN包括沒有任何呼叫的國家
LEFT JOIN city ON city.country_id = country.id
LEFT JOIN customer ON city.id = customer.city_id
LEFT JOIN call ON call.customer_id = customer.id
GROUP BY 
    country.id,
    country.country_name
-- 過濾掉不符合條件的結(jié)果
HAVING AVG(ISNULL(DATEDIFF(SECOND, call.start_time, call.end_time),0)) > (SELECT AVG(DATEDIFF(SECOND, call.start_time, call.end_time)) FROM call)

三.總結(jié)步驟

  1. 先明確需求
  2. 拆解展示字段和條件
  3. 確定所要用到的表
  4. 先寫出整體框架SQL并打印結(jié)果看數(shù)據(jù)很重要這一步
  5. 創(chuàng)建子查詢,并且測試結(jié)果,最后添加到整體框架SQL中
  6. 測試驗(yàn)證所有數(shù)據(jù)
  7. 添加備注,復(fù)雜SQL不寫備注等于沒寫

分享到:
標(biāo)簽:SQL
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定