經常使用的sql語句(找不一樣位數,找重複)

一、SQL找不一樣位數html

select length(aae135),count(1) from ac01 group by  length(aae135) ;數據庫

 

————————————————————————————————app

二、SQL查詢重複數據ide

有例表:emp函數

emp_no   name    age         001           Tom      17         002           Sun       14         003           Tom      15         004           Tom      16post

要求:學習

列出全部名字重複的人的記錄url

(1)最直觀的思路:要知道全部名字有重複人資料,首先必須知道哪一個名字重複了:htm

select   name   from   emp       group   by   name     having   count(*)>1blog

全部名字重複人的記錄是:

select   *   from   emp     where name   in   (select   name   from   emp group   by   name having count(*)>1)

(2)稍微再聰明一點,就會想到,若是對每一個名字都和原表進行比較,大於2我的名字與這條記錄相同的就是合格的 ,就有

select   *   from   emp   where   (select   count(*)   from   emp   e    where   e.name=emp.name)   >1

--注意一下這個>1,想下若是是 =1,若是是 =2 若是是>2 若是 e 是另一張表 並且是=0那結果 就更好玩了:)

這個過程是 在判斷工號爲001的 人 的時候先取得 001的 名字(emp.name) 而後和原表的名字進行比較 e.name

注意e是emp的一個別名。

再稍微想得多一點,就會想到,若是有另一個名字相同的人工號不與她他相同那麼這條記錄符合要求:

select   *   from   emp         where   exists                       (select   *   from   emp   e    where   e.name=emp.name   and   e.emp_no<>emp.emp_no)

此思路的join寫法:

select   emp.*       from   emp,emp e         where emp.name=e.name and emp.emp_no<>e.emp_no/**/ /*     這個語句較規範的   join   寫法是     select emp.* from   emp   inner join emp   e     on emp.name=e.name and emp.emp_no<>e.emp_no     但我的比較傾向於前一種寫法,關鍵是更清晰     */     b、有例表:emp     name     age     Tom       16     Sun        14     Tom       16     Tom       16

----------------------------------------------------清除重複---------------------------------------------------- 過濾掉全部多餘的重複記錄 (1)咱們知道distinct、group by 能夠過濾重複,因而就有最直觀的

select   distinct   *   from   emp     或     select   name,age   from   emp   group   by   name,age

得到須要的數據,若是可使用臨時表就有解法:

select   distinct   *   into   #tmp    from   emp       delete   from   emp       insert   into   emp   select   *   from   #tmp

(2)可是若是不可使用臨時表,那該怎麼辦? 咱們觀察到咱們沒辦法區分數據(物理位置不同,對 SQL Server來講沒有任何區別),思路天然是想辦法把數據區分出來了,既然如今的全部的列都沒辦法區分數據,惟一的辦法就是再加個列讓它區分出來,加什麼列好?最佳選擇是identity列:

alter   table   emp   add   chk   int   identity(1,1)

表示例:

name   age   chk         Tom     16     1         Sun      14     2         Tom     16     3         Tom     16     4

重複記錄能夠表示爲:

select   *   from   emp where (select   count(*)   from   emp   e   where   e.name=emp.name)>1

要刪除的是:

delete   from   emp     where (select   count(*)   from   emp   e     where   e.name=emp.name   and   e.chk>=emp.chk)>1

再把添加的列刪掉,出現結果。

alter   table   emp   drop   column   chk

(3)另外一個思路: 視圖

select   min(chk) from   emp group   by   name having   count(*)   >1

得到有重複的記錄chk最小的值,因而能夠

delete from   emp where chk   not   in (select min(chk) from   emp group   by   name)

寫成join的形式也能夠:

(1)有例表:emp

emp_no    name    age         001            Tom      17         002            Sun       14         003            Tom      15         004            Tom      16

◆要求生成序列號 (1)最簡單的方法,根據b問題的解法:

alter   table   emp   add   chk   int   identity(1,1)   或       select   *,identity(int,1,1)   chk   into   #tmp   from   emp

◆若是須要控制順序怎麼辦?

select   top   100000   *,identity(int,1,1)   chk   into   #tmp   from   emp   order   by   age

(2) 假如不能夠更改表結構,怎麼辦? 若是不能夠惟一區分每條記錄是沒有辦法的,在能夠惟一區分每條記錄的時候,可使用a 中的count的思路解決這個問題

select   emp.*,(select   count(*)   from   emp   e   where   e.emp_no<=emp.emp_no)       from   emp       order   by   (select   count(*)   from   emp   e   where   e.emp_no<=emp.emp_no)

——————————————————————————————————————————————————————————————

Group by與having理解

注意:select 後的字段,必需要麼包含在group by中,要麼包含在having 後的聚合函數裏。
1. GROUP BY 是分組查詢, 通常 GROUP BY 是和聚合函數配合使用

group by 有一個原則,就是 select 後面的全部列中,沒有使用聚合函數的列,必須出如今 group by 後面(重要)

例如,有以下數據庫表:

A    B 1    abc 1    bcd

1    asdfg

 若是有以下查詢語句(該語句是錯誤的,緣由見前面的原則)

select A,B from table group by A 

該查詢語句的意圖是想獲得以下結果(固然只是一相情願)

A     B        abc 1     bcd

       asdfg 

右邊3條如何變成一條,因此須要用到聚合函數,以下(下面是正確的寫法):

select A,count(B) as 數量 from table group by A 這樣的結果就是 A    數量 1    3 

 

2. Having

where 子句的做用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組以前過濾數據,條件中不能包含聚組函數,使用where條件顯示特定的行。

having 子句的做用是篩選知足條件的組,即在分組以後過濾數據,條件中常常包含聚組函數,使用having 條件顯示特定的組,也可使用多個分組標準進行分組。

having 子句被限制子已經在SELECT語句中定義的列和聚合表達式上。一般,你須要經過在HAVING子句中重複聚合函數表達式來引用聚合值,就如你在SELECT語句中作的那樣。例如:

SELECT A COUNT(B) FROM TABLE GROUP BY A HAVING COUNT(B)>2

 

3.使用compute和compute by   使用compute子句容許同時觀察查詢所獲得各列的數據的細節以及統計各列數據所產生的彙總列       select * from work [查詢所獲得的各列的數據的細節]       compute max(基本工資),min(基本工資) [統計以後的結果]   這個例子中沒有使用by關鍵字,返回的結果是最後添加了一行基本工資的最大值和最小值,也可增長by關鍵字.         例:select * from work order by 學歷            compute max(基本工資),min(基本工資) by 學歷         比較:select 學歷,max(基本工資),min(基本工資) from work group by 學歷         說明:1:compute子句必須與order by子句用在一塊兒              2:compute子句能夠返回多種結果集.一種是體現數據細節的數據集,能夠按分類要求進行正確的分類;另外一種在分類的基礎上進行彙總產生結果.              3:而group by子句對每一類數據分類以後只能產生一個結果,不能知道細節

 

示例學習Northwind數據庫:

非相關查詢:

1:返回每一個美國員工都爲其處理過訂單的全部客戶

--思路:1:Employees表中獲取美國員工總數2:Orders表中查詢美國員工處理的Order,對CustomerID分組後,統計其不一樣的EmployeeID正好等於美國員工總數

Select CustomerID From Orders Where EmployeeID In         --獲得美國員工服務 的客戶

(Select EmployeeID From Employees Where Country=N'USA') -- 獲得所有美國員工id

group by CustomerID                                         --按客戶分組

Having Count(Distinct EmployeeID)=                    --爲其處理訂單的distinct 員工數等於美國總員工數

(Select Count(*) From Employees Where Country=N'USA')--美國員工總數

2:

返回在每個月最後實際訂單日期發生的訂單(每個月最後訂單日期可能不是每個月最後一天)

--思路:子查詢按月分組獲得每個月最近訂單日期

Select OrderID,CustomerID,EmployeeID,OrderDate

From Orders

Where OrderDate In

(Select Max(OrderDate) From Orders Group by Convert(char(6),OrderDate,112))--112表示YYYYMMDD char(6)提取YYYYMM

 

 3.

Select字句在邏輯上是SQL語句最後進行處理的最後一步,因此,如下查詢會發生錯誤:

SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts FROM (SELECT YEAR(OrderDate) AS OrderYear, CustomerID    FROM dbo.Orders) AS D GROUP BY OrderYear ;由於group by是在Select以前進行的,那個時候orderYear這個列並無造成。

若是要查詢成功,能夠像下面進行修改:

SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts FROM (SELECT YEAR(OrderDate) AS OrderYear, CustomerID    FROM dbo.Orders) AS D GROUP BY OrderYear;還有一種很特殊的寫法:

SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts FROM (SELECT YEAR(OrderDate), CustomerID    FROM dbo.Orders) AS D(OrderYear, CustomerID) GROUP BY OrderYear;在做者眼裏,他是很是喜歡這種寫法的,由於更清晰,更明確,更便於維護。

在查詢中使用參數定向產生一批結果,這個技巧沒有什麼好說的。

嵌套查詢,在處理邏輯上是從裏向外進行執行的。

相關文章
相關標籤/搜索