九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
查詢反模式

為了最簡單地說明問題,我特地設(shè)計了一張這樣的表。

  

一、GROUP BY單值規(guī)則

  規(guī)則1:單值規(guī)則,跟在SELECT后面的列表,對于每個分組來說,必須返回且僅僅返回一個值。

  典型的表現(xiàn)就是跟在SELECT后面的列,如果沒有使用聚合函數(shù),必須出現(xiàn)在GROUP BY子句后面。

  如下面這個查詢報錯:

  

  因為對于按照部門分組之后,技術(shù)部分組有3個編號,銷售部分組有2個編號,你讓數(shù)據(jù)庫顯示哪個呢?

  如果假設(shè)你使用聚合函數(shù)COUNT(編號)之后,對于每個部門分組,就只有一個值 - 該部門下的人數(shù):

  

  下面來實戰(zhàn)下,我們希望查詢出每個部門,最高工資的那個人的姓名,部門,工資。

  

  Shit,出師不利。第一次實戰(zhàn)就錯誤了,我們來分析下。

  很明顯,上面的姓名列是不符合單值規(guī)則的。我們的一廂情愿想法是,MAX(工資)之后,SQL Server就能自動幫我們返回不符合單值規(guī)則的'姓名'。但是很遺憾,SQL Server并沒有這么做。理由如下:

  1.   如果兩個人的工資相同,那么應(yīng)該將哪個人的姓名返回?
  2.   如果我們使用的不是MAX()聚合函數(shù),而是SUM、AVG等聚合函數(shù)(沒有與之匹配的工資),那么姓名返回哪個?
  3.   如果在查詢語句中使用了兩個聚合函數(shù),如MAX(),MIN()。那么應(yīng)該返回的是MAX工資的姓名,還是MIN工資的姓名呢?

  綜上所述,數(shù)據(jù)庫是不可能能夠根據(jù)我們輸入的一個聚合函數(shù),就幫助我們判斷并顯示出不符合單值規(guī)則的列的。

  對于MYSQL來說,當(dāng)有這種不符合單值規(guī)則的列時,默認是返回這一組結(jié)果的第一條記錄。而SQLite是返回最后一條。

  因此,對于以上查詢,我們要另尋解決方案。

  解決方案1:關(guān)聯(lián)子查詢

SELECT 姓名,部門,工資 FROM 工資表 AS T1WHERE NOT EXISTS (SELECT NULL FROM 工資表 AS T2 WHERE T1.部門 = T2.部門 AND T2.工資 > T1.工資)

  輸出如下:

  

  完全符合要求。對于上面的關(guān)聯(lián)子查詢,可以理解為:

  遍歷工資表的所有記錄,查找不存在比當(dāng)前記錄部門相同且工資還大的記錄。

  雖然,關(guān)聯(lián)子查詢的語法非常簡單,但是性能并不好。因為對于每一條記錄,都要執(zhí)行一次子查詢。

  解決方案2:衍生表

   使用衍生表的思路是,先執(zhí)行一個子查詢,得到一個臨時結(jié)果集,然后用臨時結(jié)果集和原表進行INNER JOIN操作。就能得到最高工資的人的信息。

  

  剛寫出這個SQL語句時,覺得非常妙,理解了之后覺得非常妙。

SELECT 姓名,T1.部門,工資 FROM 工資表 AS T1 INNER JOIN(    SELECT 部門,MAX(工資) AS 最高 FROM 工資表    --執(zhí)行查詢,先記錄兩個字段 部門-最高工資    GROUP BY 部門) AS T2        --衍生表T2ON T1.部門 = T2.部門 AND 工資 = 最高

  衍生表的方式性能優(yōu)于關(guān)聯(lián)子查詢,因為衍生表的方式只執(zhí)行了一次子查詢。但是它需要一張臨時表來存儲臨時記錄。因此,這個方案也并不是最佳的解決方案。

  解決方案3:使用JOIN + IS NULL

  這是一個更妙的解決方案,當(dāng)我們用一個外聯(lián)結(jié)去匹配記錄時,當(dāng)匹配的記錄不存在,就會用NULL來代替相應(yīng)的列。

  我們先來看一條非常簡答的SQL語句:

  

  從中你看到了什么?當(dāng)T2表中,不存在比T1表中工資高的記錄時就返回NULL。

  那么,那么,那么一個IS NULL是不是就解決問題了呢?

  

  好妙,好妙的方法,讓人拍案叫絕的使用了OUTER JOIN。

  JOIN解決方案適用于針對大量數(shù)據(jù)查詢并且可伸縮比較時。它總是能比基于子查詢的解決方案更好地適應(yīng)數(shù)據(jù)量的變量。

  解決方案4:對額外的列使用聚合函數(shù)

  我們知道,GROUP BY時,SELECT列表必須返回的是單值,那么我們可不可以通過使用聚合函數(shù),讓這個列返回單值呢?答案是可以的。

  

  其實,返回的數(shù)據(jù)是有問題的,當(dāng)工資相同時,它就返回按姓名從大到小排列的第一個姓名。也就是說,當(dāng)工資相同時,它只能夠返回一條記錄。

  我們將聚合函數(shù)換成MIN看看。

  

  解決方案5:Row_Number() + OVER

  WITH B AS  (      SELECT row_number() OVER(PARTITION BY Name ORDER BY CreateTime) AS part ,Score, Name, CreateTime      FROM xxx  )  SELECT * FROM B WHERE Part = 1

 

  輸出如下:

  

二、HAVING的理解

  WHERE與HAVING的區(qū)別:

  •   WHERE(分組前過濾):WHERE不能對聚合函數(shù)列進行過濾,因為執(zhí)行WHERE的時候,分組尚未執(zhí)行,聚合函數(shù)也未執(zhí)行。
  •   HAVING(分組后過濾):主要用于對聚合函數(shù)列進行過濾,因為HAVING實在分組之后執(zhí)行的。HAVING子句只能配合GROUP BY子句使用。沒有GROUP BY子句時不能使用HAVING。

  錯誤使用WHERE的示例:

  

  正確使用WHERE與HAVING的示例:

  

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Mysql基礎(chǔ)部分總結(jié)
重要!很重要!非常重要!理解PQ里的數(shù)據(jù)結(jié)構(gòu)(四、根據(jù)內(nèi)容定位及篩選行)
學(xué)好這25個Excel函數(shù)能漲工資,可怕你居然不知道!
用excel vlookup 函數(shù)如何快速制作工資條
用函數(shù)制作工資條,這兩個方法太快了
Excel最新工資管理套表,自動員工部門查詢匯總,輕簡操作不加班
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服