1. 程式人生 > >各種SQL查詢技巧彙總 (轉)

各種SQL查詢技巧彙總 (轉)

select
select * from student;

all 查詢所有
select all sex from student;

distinct 過濾重複
select distinct sex from student;

count 統計
select count(*) from student;
select count(sex) from student;
select count(distinct sex) from student;

top 取前N條記錄
select top 3 * from student;

alias column name 列重新命名
select id as 編號, name ‘名稱’, sex 性別 from student;

alias table name 表重新命名
select id, name, s.id, s.name from student s;

column 列運算
select (age + id) col from student;
select s.name + ‘-’ + c.name from classes c, student s where s.cid = c.id;

where 條件
select * from student where id = 2;
select * from student where id > 7;
select * from student where id < 3;
select * from student where id <> 3;
select * from student where id >= 3;
select * from student where id <= 5;
select * from student where id !> 3;
select * from student where id !< 5;

and 並且
select * from student where id > 2 and sex = 1;

or 或者
select * from student where id = 2 or sex = 1;

between … and … 相當於並且
select * from student where id between 2 and 5;
select * from student where id not between 2 and 5;

like 模糊查詢
select * from student where name like ‘%a%’;
select * from student where name like ‘%[a][o]%’;
select * from student where name not like ‘%a%’;
select * from student where name like ‘ja%’;
select * from student where name not like ‘%[j,n]%’;
select * from student where name like ‘%[j,n,a]%’;
select * from student where name like ‘%[^ja,as,on]%’;
select * from student where name like ‘%[ja_on]%’;

in 子查詢
select * from student where id in (1, 2);

not in 不在其中
select * from student where id not in (1, 2);

is null 是空
select * from student where age is null;

is not null 不為空
select * from student where age is not null;

order by 排序
select * from student order by name;
select * from student order by name desc;
select * from student order by name asc;

group by 分組
按照年齡進行分組統計
select count(age), age from student group by age;
按照性別進行分組統計
select count(*), sex from student group by sex;
按照年齡和性別組合分組統計,並排序
select count(*), sex from student group by sex, age order by age;
按照性別分組,並且是id大於2的記錄最後按照性別排序
select count(*), sex from student where id > 2 group by sex order by sex;
查詢id大於2的資料,並完成運算後的結果進行分組和排序
select count(), (sex id) new from student where id > 2 group by sex * id order by sex * id;

group by all 所有分組
按照年齡分組,是所有的年齡
select count(*), age from student group by all age;

having 分組過濾條件
按照年齡分組,過濾年齡為空的資料,並且統計分組的條數和現實年齡資訊
select count(*), age from student group by age having age is not null;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

按照年齡和cid組合分組,過濾條件是cid大於1的記錄 
select count(*), cid, sex from student group by cid, sex having cid > 1;

按照年齡分組,過濾條件是分組後的記錄條數大於等於2 
select count(*), age from student group by age having count(age) >= 2;

按照cid和性別組合分組,過濾條件是cid大於1,cid的最大值大於2 
select count(*), cid, sex from student group by cid, sex having cid > 1 and max(cid) > 2; 
巢狀子查詢

子查詢是一個巢狀在select、insert、update或delete語句或其他子查詢中的查詢。任何允許使用表示式的地方都可以使用子查詢。子查詢也稱為內部查詢或內部選擇,而包含子查詢的語句也成為外部查詢或外部選擇。

from (select … table)示例

將一個table的查詢結果當做一個新表進行查詢 
select * from ( 
select id, name from student where sex = 1 
) t where t.id > 2; 
上面括號中的語句,就是子查詢語句(內部查詢)。在外面的是外部查詢,其中外部查詢可以包含以下語句: 
1、 包含常規選擇列表元件的常規select查詢 
2、 包含一個或多個表或檢視名稱的常規from語句 
3、 可選的where子句 
4、 可選的group by子句 
5、 可選的having子句 
示例

查詢班級資訊,統計班級學生人生 
select , (select count() from student where cid = classes.id) as num 
from classes order by num; 
in, not in子句查詢示例

查詢班級id大於小於的這些班級的學生資訊 
select * from student where cid in ( 
select id from classes where id > 2 and id < 4 
);

查詢不是班的學生資訊 
select * from student where cid not in ( 
select id from classes where name = ‘2班’ 

in、not in 後面的子句返回的結果必須是一列,這一列的結果將會作為查詢條件對應前面的條件。如cid對應子句的id; 
exists和not exists子句查詢示例

查詢存在班級id為的學生資訊 
select * from student where exists ( 
select * from classes where id = student.cid and id = 3 
);

查詢沒有分配班級的學生資訊 
select * from student where not exists ( 
select * from classes where id = student.cid 
); 
exists和not exists查詢需要內部查詢和外部查詢進行一個關聯的條件,如果沒有這個條件將是查詢到的所有資訊。如:id等於student.id; 
some、any、all子句查詢示例

查詢班級的學生年齡大於班級的學生的年齡的資訊 
select * from student where cid = 5 and age > all ( 
select age from student where cid = 3 
);

select * from student where cid = 5 and age > any ( 
select age from student where cid = 3 
);

select * from student where cid = 5 and age > some ( 
select age from student where cid = 3 
); 
聚合查詢

1、 distinct去掉重複資料 
select distinct sex from student; 
select count(sex), count(distinct sex) from student;

2、 compute和compute by彙總查詢 
對年齡大於的進行彙總 
select age from student 
where age > 20 order by age compute sum(age) by age;

對年齡大於的按照性別進行分組彙總年齡資訊 
select id, sex, age from student 
where age > 20 order by sex, age compute sum(age) by sex;

按照年齡分組彙總 
select age from student 
where age > 20 order by age, id compute sum(age);

按照年齡分組,年齡彙總,id找最大值 
select id, age from student 
where age > 20 order by age compute sum(age), max(id); 
compute進行彙總前面是查詢的結果,後面一條結果集就是彙總的資訊。compute子句中可以新增多個彙總表示式,可以新增的資訊如下: 
a、 可選by關鍵字。它是每一列計算指定的行聚合 
b、 行聚合函式名稱。包括sum、avg、min、max、count等 
c、 要對其執行聚合函式的列 
compute by適合做先分組後彙總的業務。compute by後面的列一定要是order by中出現的列。

3、 cube彙總 
cube彙總和compute效果類似,但語法較簡潔,而且返回的是一個結果集。 
select count(*), sex from student group by sex with cube; 
select count(*), age, sum(age) from student where age is not null group by age with cube; 
cube要結合group by語句完成分組彙總 
排序函式

排序在很多地方需要用到,需要對查詢結果進行排序並且給出序號。比如: 
1、 對某張表進行排序,序號需要遞增不重複的 
2、 對學生的成績進行排序,得出名次,名次可以並列,但名次的序號是連續遞增的 
3、 在某些排序的情況下,需要跳空序號,雖然是並列 
基本語法 
排序函式 over([分組語句] 排序子句[desc][asc]) 
排序子句 order by 列名, 列名 
分組子句 partition by 分組列, 分組列 
row_number函式

根據排序子句給出遞增連續序號 
按照名稱排序的順序遞增 
select s.id, s.name, cid, c.name, row_number() over(order by c.name) as number 
from student s, classes c where cid = c.id; 
rank函式函式

根據排序子句給出遞增的序號,但是存在並列並且跳空 
順序遞增 
select id, name, rank() over(order by cid) as rank from student;

跳過相同遞增 
select s.id, s.name, cid, c.name, rank() over(order by c.name) as rank 
from student s, classes c where cid = c.id; 
dense_rank函式

根據排序子句給出遞增的序號,但是存在並列不跳空 
不跳過,直接遞增 
select s.id, s.name, cid, c.name, dense_rank() over(order by c.name) as dense 
from student s, classes c where cid = c.id; 
partition by分組子句

可以完成對分組的資料進行增加排序,partition by可以與以上三個函式聯合使用。 
利用partition by按照班級名稱分組,學生id排序 
select s.id, s.name, cid, c.name, row_number() over(partition by c.name order by s.id) as rank 
from student s, classes c where cid = c.id;

select s.id, s.name, cid, c.name, rank() over(partition by c.name order by s.id) as rank 
from student s, classes c where cid = c.id;

select s.id, s.name, cid, c.name, dense_rank() over(partition by c.name order by s.id) as rank 
from student s, classes c where cid = c.id; 
ntile平均排序函式

將要排序的資料進行平分,然後按照等分排序。ntile中的引數代表分成多少等分。 
select s.id, s.name, cid, c.name, 
ntile(5) over(order by c.name) as ntile 
from student s, classes c where cid = c.id; 
集合運算

操作兩組查詢結果,進行交集、並集、減集運算 
1、 union和union all進行並集運算 
–union 並集、不重複 
select id, name from student where name like ‘ja%’ 
union 
select id, name from student where id = 4;

–並集、重複 
select * from student where name like ‘ja%’ 
union all 
select * from student;

2、 intersect進行交集運算 
–交集(相同部分) 
select * from student where name like ‘ja%’ 
intersect 
select * from student;

3、 except進行減集運算 
–減集(除相同部分) 
select * from student where name like ‘ja%’ 
except 
select * from student where name like ‘jas%’; 
公式表表達式

查詢表的時候,有時候中間表需要重複使用,這些子查詢被重複查詢呼叫,不但效率低,而且可讀性低,不利於理解。那麼公式表表達式可以解決這個問題。 
我們可以將公式表表達式(CET)視為臨時結果集,在select、insert、update、delete或是create view語句的執行範圍內進行定義。 
– 表示式 
with statNum(id, num) as 

select cid, count(*) 
from student 
where id > 0 
group by cid 

select id, num from statNum order by id;

with statNum(id, num) as 

select cid, count(*) 
from student 
where id > 0 
group by cid 

select max(id), avg(num) from statNum; 
連線查詢

1、 簡化連線查詢

簡化聯接查詢
select s.id, s.name, c.id, c.name from student s, classes c where s.cid = c.id;
  • 1
  • 2
  • 3

2、 left join左連線

左連線
select s.id, s.name, c.id, c.name from student s left join classes c on s.cid = c.id;
  • 1
  • 2
  • 3

3、 right join右連線

右連線
select s.id, s.name, c.id, c.name from student s right join classes c on s.cid = c.id;
  • 1
  • 2
  • 3

4、 inner join內連線

內連線
select s.id, s.name, c.id, c.name from student s inner join classes c on s.cid = c.id;

inner可以省略
select s.id, s.name, c.id, c.name from student s join classes c on s.cid = c.id;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1、 聚合函式 
max最大值、min最小值、count統計、avg平均值、sum求和、var求方差 
select 
max(age) max_age, 
min(age) min_age, 
count(age) count_age, 
avg(age) avg_age, 
sum(age) sum_age, 
var(age) var_age 
from student;

2、 日期時間函式 
select dateAdd(day, 3, getDate());–加天 
select dateAdd(year, 3, getDate());–加年 
select dateAdd(hour, 3, getDate());–加小時 
–返回跨兩個指定日期的日期邊界數和時間邊界數 
select dateDiff(day, ‘2011-06-20’, getDate()); 
–相差秒數 
select dateDiff(second, ‘2011-06-22 11:00:00’, getDate()); 
–相差小時數 
select dateDiff(hour, ‘2011-06-22 10:00:00’, getDate()); 
select dateName(month, getDate());–當前月份 
select dateName(minute, getDate());–當前分鐘 
select dateName(weekday, getDate());–當前星期 
select datePart(month, getDate());–當前月份 
select datePart(weekday, getDate());–當前星期 
select datePart(second, getDate());–當前秒數 
select day(getDate());–返回當前日期天數 
select day(‘2011-06-30’);–返回當前日期天數 
select month(getDate());–返回當前日期月份 
select month(‘2011-11-10’); 
select year(getDate());–返回當前日期年份 
select year(‘2010-11-10’); 
select getDate();–當前系統日期 
select getUTCDate();–utc日期