SQL Server 面试题 (持续更新中...)

asp.net 专栏收录该内容
11 篇文章 0 订阅

3。表内容如下
  -----------------------------
  ID LogTime
  1 2008/10/10 10:00:00
  1 2008/10/10 10:03:00
  1 2008/10/10 10:09:00
  2 2008/10/10 10:10:00
  2 2008/10/10 10:11:00
  ......
  -----------------------------
  请问各位高手,如何查询登陆时间间隔不超过5分钟的所有记录.
  
  几道经典的SQL笔试题目(有答案)
  (2)表名:成绩表
  姓名 课程 分数
  张三 语文 81
  张三 数学 75
  李四 语文 56
  李四 数学 90
  王五 语文 81
  王五 数学 100
  王五 英语 49
  ……
  (其他用户实验的记录大家可自行插入)
  给出成绩全部合格的学生信息(包含姓名、课程、分数),注:分数在60以上评为合格
  select * from score
  where s_name not in
  (select s_name from score
  where score<60)
  或者:
  select * from score where s_name in
  (select s_name from score
  group by s_name
  having min(score)>=60)
  (3)表名:商品表
  名称 产地 进价
  苹果 烟台 2.5
  苹果 云南 1.9
  苹果 四川 3
  西瓜 江西 1.5
  西瓜 北京 2.4
  ……
  (其他用户实验的记录大家可自行插入)
  给出平均进价在2元以下的商品名称
  select 名称 from 商品表 group by 名称 having avg(进价) < 2
  (4)表名:高考信息表
  准考证号 科目 成绩
  2006001 语文 119
  2006001 数学 108
  2006002 物理 142
  2006001 化学 136
  2006001 物理 127
  2006002 数学 149
  2006002 英语 110
  2006002 语文 105
  2006001 英语 98
  2006002 化学 129
  ……
  (其他用户实验的记录大家可自行插入)
  给出高考总分在600以上的学生准考证号
  select 准考证号 from 高考信息表 group by 准考证号 having sum(成绩) > 600
  (5)表名:高考信息表
  准考证号 数学 语文 英语 物理 化学
  2006001 108 119 98 127 136
  2006002 149 105 110 142 129
  ……
  (其他用户实验的记录大家可自行插入)
  给出高考总分在600以上的学生准考证号
  select 准考证号 from 高考信息表 where (数学+语文+英语+物理+化学) > 600
  (四部分)
  (一)表名:club
  id gender age
  67 M 19
  68 F 30
  69 F 27
  70 F 16
  71 M 32
  ……(其余测试数据请自行插入)
  查询出该俱乐部里男性会员和女性会员的总数
  select gender,count(id) from club group by gender
  (二)表名:team
  ID(number型) Name(varchar2型)
  1 a
  2 b
  3 b
  4 a
  5 c
  6 c
  要求:执行一个删除语句,当Name列上有相同时,只保留ID这列上值小的
  例如:删除后的结果应如下:
  ID(number型) Name(varchar2型)
  1 a
  2 b
  5 c
  请写出SQL语句。
  delete from team where id not in
  (
   select min(a1.id) from team a1
   where a1.name=team.name )
  delete from team where id not in
  (
  select min(id) from team group by name)
  (三)表名:student
  name course score
  张青 语文 72
  王华 数学 72
  张华 英语 81
  张青 物理 67
  李立 化学 98
  张燕 物理 70
  张青 化学 76
  查询出“张”姓学生中平均成绩大于75分的学生信息
  select * from student where name in
  (select name from student
  where name like '张%'
  group by name having avg(score) > 75)

Sql常见面试题(总结)
0.如何删除一个拥有比较多的数据的表
如果该表所在的数据库拥有较少的表,可以先将其余表导出去,然后分离数据库,在删除,新建一个同名数据库,将其余表再次导入。
1.用一条SQL语句 查询出每门课都大于80分的学生姓名 
name kecheng fenshu
张三     语文    81
张三     数学    75
李四     语文    76
李四     数学    90
王五     语文    81
王五     数学    100
王五     英语    90
A: select distinct name from table   where   name not in (select distinct name from table where fenshu<=80)
2.学生表 如下:
自动编号 学号 姓名 课程编号 课程名称 分数
1        2005001   张三   0001    数学 69
2        2005002   李四   0001    数学 89
3        2005001   张三   0001    数学 69
删除除了自动编号不同,其他都相同的学生冗余信息
A: delete tablename where 自动编号 not in(select min(自动编号) from tablename group by 学号,姓名,课程编号,课程名称,分数)
一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.
你先按你自己的想法做一下,看结果有我的这个简单吗?
答:select a.name, b.name
from team a, team b
where a.name < b.name
请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。
AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。
数据库名:JcyAudit,数据集:Select * from TestDB
答:select a.*
from TestDB a
,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101' group by Occmonth) b
where a.Occmonth=b.Occmonth and a.DebitOccur>b.Debit101ccur
************************************************************************************
面试题:怎么把这样一个表儿
year   month amount
1991 1     1.1
1991 2     1.2
1991 3     1.3
1991 4     1.4
1992 1     2.1
1992 2     2.2
1992 3     2.3
1992 4     2.4
查成这样一个结果
year m1   m2   m3   m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4
答案一、
select year,
(select amount from   aaa m where month=1   and m.year=aaa.year) as m1,
(select amount from   aaa m where month=2   and m.year=aaa.year) as m2,
(select amount from   aaa m where month=3   and m.year=aaa.year) as m3,
(select amount from   aaa m where month=4   and m.year=aaa.year) as m4
from aaa   group by year
这个是ORACLE   中做的:
select * from (select name, year b1, lead(year) over
(partition by name order by year) b2, lead(m,2) over(partition by name order by year) b3,rank()over(
partition by name order by year) rk from t) where rk=1;
************************************************************************************
精妙的SQL语句!
精妙SQL语句 
作者:不详 发文时间:2003.05.29 10:55:05
说明:复制表(只复制结构,源表名:a 新表名:b)
SQL: select * into b from a where 1<>1
说明:拷贝表(拷贝数据,源表名:a 目标表名:b)
SQL: insert into b(a, b, c) select d,e,f from b;
说明:显示文章、提交人和最后回复时间
SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
说明:外连接查询(表名1:a 表名2:b)
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
说明:日程安排提前五分钟提醒
SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5
说明:两张关联表,删除主表中已经在副表中没有的信息
SQL:
delete from info where not exists ( select * from infobz where info.infid=infobz.infid )
说明:--
SQL:
SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE
FROM TABLE1,
(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE
FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X,
(SELECT NUM, UPD_DATE, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE,'YYYY/MM') =
TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y,
WHERE X.NUM = Y.NUM (+)
AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B
WHERE A.NUM = B.NUM
说明:--
SQL:
select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&strdepartmentname&"' and 专业名称='"&strprofessionname&"' order by 性别,生源地,高考总成绩
说明:
从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)
SQL:
SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC
FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration
FROM TELFEESTAND a, TELFEE b
WHERE a.tel = b.telfax) a
GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy')
说明:四表联查问题:
SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....
说明:得到表中最小的未使用的ID号
SQL:
SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID
FROM Handle
WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)
*******************************************************************************
有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value换为A中对应的value
这道题的SQL语句怎么写?
update b set b.value=(select a.value from a where a.key=b.key) where b.id in(select b.id from b,a where b.key=a.key);
***************************************************************************
高级sql面试题
原表:
courseid coursename score
-------------------------------------
1 java 70
2 oracle 90
3 xml 40
4 jsp 30
5 servlet 80
-------------------------------------
为了便于阅读,查询此表后的结果显式如下(及格分数为60):
courseid coursename score mark
---------------------------------------------------
1 java 70 pass
2 oracle 90 pass
3 xml 40 fail
4 jsp 30 fail
5 servlet 80 pass
---------------------------------------------------
写出此查询语句
没有装ORACLE,没试过
select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course
完全正确
SQL> desc course_v
Name Null? Type
----------------------------------------- -------- ----------------------------
COURSEID NUMBER
COURSENAME VARCHAR2(10)
SCORE NUMBER
SQL> select * from course_v;
COURSEID COURSENAME SCORE
---------- ---------- ----------
1 java 70
2 oracle 90
3 xml 40
4 jsp 30
5 servlet 80
SQL> select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course_v;
COURSEID COURSENAME SCORE MARK
---------- ---------- ---------- ----
1 java 70 pass
2 oracle 90 pass
3 xml 40 fail
4 jsp 30 fail
5 servlet 80 pass
*******************************************************************************
原表:
id proid proname
1 1 M
1 2 F
2 1 N
2 2 G
3 1 B
3 2 A
查询后的表:
id pro1 pro2
1 M F
2 N G
3 B A
写出查询语句
解决方案
sql求解
表a
列 a1 a2
记录 1 a
1 b
2 x
2 y
2 z
用select能选成以下结果吗?
1 ab
2 xyz
使用pl/sql代码实现,但要求你组合后的长度不能超出oracle varchar2长度的限制。
下面是一个例子
create or replace type strings_table is table of varchar2(20);
/
create or replace function merge (pv in strings_table) return varchar2
is
ls varchar2(4000);
begin
for i in 1..pv.count loop
ls := ls || pv(i);
end loop;
return ls;
end;
/
create table t (id number,name varchar2(10));
insert into t values(1,'Joan');
insert into t values(1,'Jack');
insert into t values(1,'Tom');
insert into t values(2,'Rose');
insert into t values(2,'Jenny');
column names format a80;
select t0.id,merge(cast(multiset(select name from t where t.id = t0.id) as strings_table)) names
from (select distinct id from t) t0;
drop type strings_table;
drop function merge;
drop table t;

用sql:
Well if you have a thoretical maximum, which I would assume you would given the legibility of listing hundreds of employees in the way you describe then yes. But the SQL needs to use the LAG function for each employee, hence a hundred emps a hundred LAGs, so kind of bulky.
This example uses a max of 6, and would need more cut n pasting to do more than that.
SQL> select deptno, dname, emps
2 from (
3 select d.deptno, d.dname, rtrim(e.ename ||', '||
4 lead(e.ename,1) over (partition by d.deptno
5 order by e.ename) ||', '||
6 lead(e.ename,2) over (partition by d.deptno
7 order by e.ename) ||', '||
8 lead(e.ename,3) over (partition by d.deptno
9 order by e.ename) ||', '||
10 lead(e.ename,4) over (partition by d.deptno
11 order by e.ename) ||', '||
12 lead(e.ename,5) over (partition by d.deptno
13 order by e.ename),', ') emps,
14 row_number () over (partition by d.deptno
15 order by e.ename) x
16 from emp e, dept d
17 where d.deptno = e.deptno
18 )
19 where x = 1
20 /
DEPTNO DNAME EMPS
------- ----------- ------------------------------------------
10 ACCOUNTING CLARK, KING, MILLER
20 RESEARCH ADAMS, FORD, JONES, ROONEY, SCOTT, SMITH
30 SALES ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD
also
先create function get_a2;
create or replace function get_a2( tmp_a1 number)
return varchar2
is
Col_a2 varchar2(4000);
begin
Col_a2:='';
for cur in (select a2 from unite_a where a1=tmp_a1)
loop
Col_a2=Col_a2||cur.a2;
end loop;
return Col_a2;
end get_a2;
select distinct a1 ,get_a2(a1) from unite_a
1 ABC
2 EFG
3 KMN
*******************************************************************************
一个SQL 面试题
去年应聘一个职位未果,其间被考了一个看似简单的题,但我没有找到好的大案.
不知各位大虾有无好的解法?

题为:
有两个表, t1, t2,
Table t1:
SELLER | NON_SELLER
----- -----
A B
A C
A D
B A
B C
B D
C A
C B
C D
D A
D B
D C

Table t2:
SELLER | COUPON | BAL
----- --------- ---------
A 9 100
B 9 200
C 9 300
D 9 400
A 9.5 100
B 9.5 20
A 10 80
要求用SELECT 语句列出如下结果:------如A的SUM(BAL)为B,C,D的和,B的SUM(BAL)为A,C,D的和.......
且用的方法不要增加数据库负担,如用临时表等.
NON-SELLER| COUPON | SUM(BAL) ------- --------
A 9 900
B 9 800
C 9 700
D 9 600
A 9.5 20
B 9.5 100
C 9.5 120
D 9.5 120
A 10 0
B 10 80
C 10 80
D 10 80
关于论坛上那个SQL微软面试题
问题:
一百个账户各有100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后,请输出每天所有账户的余额信息

这个问题的难点在于每个用户在某天可能有多条纪录,也可能一条纪录也没有(不包括第一天)
返回的记录集是一个100天*100个用户的纪录集
下面是我的思路:
1.创建表并插入测试数据:我们要求username从1-100
CREATE TABLE [dbo].[TABLE2] (
[username] [varchar] (50) NOT NULL , --用户名
[outdate] [datetime] NOT NULL , --日期
[cash] [float] NOT NULL --余额
) ON [PRIMARY
declare @i int
set @i=1
while @i<=100
   begin
insert table2 values(convert(varchar(50),@i),'2001-10-1',100)
insert table2 values(convert(varchar(50),@i),'2001-11-1',50)
set @i=@i+1
   end
insert table2 values(convert(varchar(50),@i),'2001-10-1',90)
select * from table2 order by outdate,convert(int,username)
2.组合查询语句:
a.我们必须返回一个从第一天开始到100天的纪录集:
如:2001-10-1(这个日期是任意的) 到 2002-1-8
由于第一天是任意一天,所以我们需要下面的SQL语句:
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
这里的奥妙在于:
convert(int,username)-1(记得我们指定用户名从1-100 :-))
group by username,min(outdate):第一天就可能每个用户有多个纪录。
返回的结果:
outdate                                             
------------------------------------------------------
2001-10-01 00:00:00.000
.........
2002-01-08 00:00:00.000
b.返回一个所有用户名的纪录集:
select distinct username from table2
返回结果:
username                                       
--------------------------------------------------
1
10
100
......
99
c.返回一个100天记录集和100个用户记录集的笛卡尔集合:
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join
(
select distinct username from table2
) as B
order by outdate,convert(int,username)
返回结果100*100条纪录:
outdate                         username
2001-10-01 00:00:00.000          1
......
2002-01-08 00:00:00.000          100
d.返回当前所有用户在数据库的有的纪录:
select outdate,username,min(cash) as cash from table2
group by outdate,username
order by outdate,convert(int,username)
返回纪录:
outdate                         username cash
2001-10-01 00:00:00.000          1       90
......
2002-01-08 00:00:00.000          100        50
e.将c中返回的笛卡尔集和d中返回的纪录做left join:
select C.outdate,C.username,
D.cash
from
(
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join
(
select distinct username from table2
) as B
) as C
left join
(
select outdate,username,min(cash) as cash from table2
group by outdate,username
) as D
on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)
order by C.outdate,convert(int,C.username)
注意:用户在当天如果没有纪录,cash字段返回NULL,否则cash返回每个用户当天的余额
outdate                         username cash
2001-10-01 00:00:00.000          1       90
2001-10-01 00:00:00.000          2       100
......
2001-10-02 00:00:00.000          1       90
2001-10-02 00:00:00.000          2       NULL   <--注意这里
......
2002-01-08 00:00:00.000          100        50
f.好了,现在我们最后要做的就是,如果cash为NULL,我们要返回小于当前纪录日期的第一个用户余额(由于我们使用order by cash,所以返回top 1纪录即可,使用min应该也可以),这个余额即为当前的余额:
case isnull(D.cash,0)
when 0 then
(
select top 1 cash from table2 where table2.username=C.username
and datediff(d,C.outdate,table2.outdate)<0
order by table2.cash
)
else D.cash
end as cash
g.最后组合的完整语句就是
select C.outdate,C.username,
case isnull(D.cash,0)
when 0 then
(
select top 1 cash from table2 where table2.username=C.username
and datediff(d,C.outdate,table2.outdate)<0
order by table2.cash
)
else D.cash
end as cash
from
(
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join
(
select distinct username from table2
) as B
) as C
left join
(
select outdate,username,min(cash) as cash from table2
group by outdate,username
) as D
on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)
order by C.outdate,convert(int,C.username)
返回结果:
outdate                               username        cash
2001-10-01 00:00:00.000 1                    90
2001-10-01 00:00:00.000 2                100
......
2002-01-08 00:00:00.000 100             50
***********************************************************************************
取出sql表中第31到40的记录(以自动增长ID为主键)
*从数据表中取出第n条到第m条的记录*/
declare @m int
declare @n int
declare @sql varchar(800)
set @m=40
set @n=31
set @sql='select top '+str(@m-@n+1) + '* from idetail where autoid not in(
select top '+ str(@n-1) + 'autoid from idetail)'
exec(@sql)

select top 10 * from t where id not in (select top 30 id from t order by id ) orde by id
--------------------------------------------------------------------------------
select top 10 * from t where id in (select top 40 id from t order by id) order by id desc
*******************************************************************************
一道面试题,写sql语句
有表a存储二叉树的节点,要用一条sql语句查出所有节点及节点所在的层.
表a
c1 c2 A ----------1
---- ---- / /
A B B C --------2
A C / / /
B D D N E ------3
C E / / /
D F F K I ---4
E I
D K
C N

所要得到的结果如下
jd cs
----- ----
A 1
B 2
C 2
D 3
N 3
E 3
F 4
K 4
I 4
有高手指导一下,我只能用pl/sql写出来,请教用一条sql语句的写法
SQL> select c2, level + 1 lv
2 from test start
3 with c1 = 'A'
4 connect by c1 = prior c2
5 union
6 select 'A', 1 from dual
7 order by lv;
C2 LV
-- ----------
A 1
B 2
C 2
D 3
E 3
N 3
F 4
I 4
K 4
已选择9行

 个表之间的关联查询

   在数据库操作中,有很多时候不是对某一个表进行数据库操作,通常还会把其他表的字段的值也传递过来。不过这连个表不是没有关系的。通常通过索引或者健关联起来

       如下为一个例子。

       表一。表名称tb1.其中studentID为主索引。外健。

studentID

studentName

studentGender

studntAge

3102079014

刘永相



25

3102079015

赵某某



23

       表二。表名称tb2.其中teacherID为主索引。外健。

teacherID

teacherName

teacherManageStudent

teacherMemo

3645221

刘刚

3102079014

备注无

3645222

成昆

3102079015

备注无

       现在有一个查询,需要知道某一个老师管理的学生的名字。由表二可以知道老师刘刚管理的是3102079014这个学生,又由表1知道3102079014这个学生的名称为刘永相。怎么写这个查询语句呢?

       如下:

       sql=select tb2.teacherName,tb1.studentName for tb2,tb1 where tb2.teacherManageStuent=tb1.studentID

       出来的结果为:

teacherName

studentName

刘刚

刘永相

       可能读者马上就会产生一个疑问,在表2里头。teacherID作为索引,必然只有唯一的一个ID记录。那么我怎么来管理所有的学生呢?

       由两个处理的方法。1:在teacherManageStudent字段里头把所有的学生的ID都录进去。中间用!或者其他符号表示出来,在后面的sql生成的时候,用一个循环来不断地把所有的学生得ID都写入sql.:2:tb2不要建成如上的形式,在tb2里放置老师的基本信息。另外一个新表里头放置的老师的ID和老师管理学生ID的记录,如下:

新表:表名称tb3

teacherID

teacherManageStudent

3645221

3102079014

其中表2变成了

teacherID

teacherName

teacherMemo

3645221

刘刚

备注无

3645222

成昆

备注无

------------------------------------------------------------------------------------------

只要参与连结的表之间有一些逻辑关联存在,SQLServer就可以通过使用连结来从多个表产生关联并返回数据。连结可以在SELECT语句中的FORM子句或WHERE子句中被指定。


实践中,最好让你的连结保留在FORM子句里,因为这是SQL标准指定的。下面是你将用到的三个基本的连结类型:


•内连结(INNERJOIN)—内连结是你将要用到的最常见的连结操作。它将会使用一个比较操作符,像等于(=)或不等于(<>)。一个内连结操作将以两个表中共同的值为基础来匹配两个表中的行。关于该连结的一个例子是,将authors表和titles表中作者标识相同的行从数据库中检索出来。


•全连结将不管另一边的表是否有匹配行而检索出两表中所有的行。


•右连结(RIGHTJOIN)将检索右边表中所有行和左边表中与右边表相匹配的行。如果在左边没有与右边相匹配的行,则在该位置返回一个空值。


•左连结(LEFTJOIN)将从连结左边的表中检索所有的行,而不仅仅是那些匹配的行。如果左边表中的行在右边表中没有相匹配行,检索的结果中对应右边表的列将包含空值。这种连接可用于返回一张图书馆中所有书的清单。如果这本书被清点过,清点这本书的人的姓名将出现在右边列中;否则,该字段为空值。


•外连结(OUTERJOIN)—外连接是不常用的一种比较形式。这种类型的连结有三种不同的方式:右连结、左连结和全连结。


•交叉连结(CROSSJOIN)—交叉连结是返回左表所有行并匹配上右表所有行的一种特殊的连结类型。如果左右两表各有10行,SQLServer将返回100行。交叉连结的结果也被当作是一种笛卡尔乘积。现在你已经知道连结是什么了,接下来我们看一些连结的实际应用。下面的SQL语句,将用内连结找出哪些作者和他们的出版商同住一个州,以及这是哪家出版公司。


SQL语句如下:


selectauthors.au_lname+','+authors.au_fnameAS'Name',publishers.pub_name,publishers.statefromauthorsinnerjoinpublishersonauthors.state=publishers.stateorderby'Name'

 

 

这个查询的结果将告诉你有15位作者与他们的出版公司在同一个州,而且他们均为同一个公司即Algodata Infosystems公司工作。

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

baoxuetianxia

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值