SQL中大概有这么几种JOIN:
cross join
inner join
left outer join
right outer join
full outer join
他们都是基于cross join(笛卡尔乘积),举例说明
A_test表
Id a_name a_describe
1 a11111 a11111
2 a22222 a22222
3 a33333 a33333
B_test表
Id b_name b_describe
1 b11111 01
1 b11111 02
2 b22222 01
2 b22222 02
3 b44444 04
select * from a_test a //查询出所有a表中的所有记录 3条
select * from b_test b //查询出所有b表中的所有记录 5条
select * from a_test a cross join b_test b //a b 两表的笛卡尔乘积 即所有的组合 共15条记录
结果:
1 a11111 a111111 1 b11111 01
1 a11111 a111111 1 b11111 02
1 a11111 a111111 2 b22222 01
1 a11111 a111111 2 b22222 02
1 a11111 a111111 4 b44444 01
2 a22222 a222222 1 b11111 01
2 a22222 a222222 1 b11111 02
2 a22222 a222222 2 b22222 01
2 a22222 a222222 2 b22222 02
2 a22222 a222222 4 b44444 01
3 a33333 a333333 1 b11111 01
3 a33333 a333333 1 b11111 02
3 a33333 a333333 2 b22222 01
3 a33333 a333333 2 b22222 02
3 a33333 a333333 4 b44444 01
1 a11111 a111111 1 b11111 01
1 a11111 a111111 1 b11111 02
1 a11111 a111111 2 b22222 01
1 a11111 a111111 2 b22222 02
1 a11111 a111111 4 b44444 01
2 a22222 a222222 1 b11111 01
2 a22222 a222222 1 b11111 02
2 a22222 a222222 2 b22222 01
2 a22222 a222222 2 b22222 02
2 a22222 a222222 4 b44444 01
3 a33333 a333333 1 b11111 01
3 a33333 a333333 1 b11111 02
3 a33333 a333333 2 b22222 01
3 a33333 a333333 2 b22222 02
3 a33333 a333333 4 b44444 01
select * from a_test a inner join b_test b on a.id = b.id
//在笛卡尔乘积的结果集中去掉不符合连接条件的行 包含于笛卡尔乘积
结果:
1 a11111 a111111 1 b11111 01
1 a11111 a111111 1 b11111 02
2 a22222 a222222 2 b22222 01
2 a22222 a222222 2 b22222 02
1 a11111 a111111 1 b11111 01
1 a11111 a111111 1 b11111 02
2 a22222 a222222 2 b22222 01
2 a22222 a222222 2 b22222 02
select * from a_test a left outer join b_test b on a.id = b.id
//是在inner join的结果集上加上左面表中没被选上的不相等的记录,不包含于笛卡尔乘积
//行的右表部分每个字段都用NUll填充
结果:
1 a11111 a111111 1 b11111 01
1 a11111 a111111 1 b11111 02
2 a22222 a222222 2 b22222 01
2 a22222 a222222 2 b22222 02
3 a33333 a333333 NULL NULL NULL
select * from a_test a right join b_test b on a.id = b.id
//是在inner join的结果集上加上右面表中没被选上的不相等的记录,不包含于笛卡尔乘积
//行的左表部分每个字段都用NUll填充
1 a11111 a111111 1 b11111 01
1 a11111 a111111 1 b11111 02
2 a22222 a222222 2 b22222 01
2 a22222 a222222 2 b22222 02
NULL NULL NULL 4 b44444 01
select * from a_test a full outer join b_test b on a.id = b.id
//是在inner join的结果集上加上左、右两面表中没被选上的不相等的记录,不包含于笛卡尔乘积
//行的右、左表两部分每个字段都用NUll填充
1 a11111 a111111 1 b11111 01
1 a11111 a111111 1 b11111 02
2 a22222 a222222 2 b22222 01
2 a22222 a222222 2 b22222 02
NULL NULL NULL 4 b44444 01
3 a33333 a333333 NULL NULL NULL
******必须指出:
《1》Inner Join是笛卡尔乘积完整的一部分;但Left Join和Right Join并不是笛卡尔乘积的完整一部分,他们只是包含笛卡尔乘积中InnerJoin那部分;笛卡尔乘积中并没有Null值的那部分记录。
《2》他们的否定语句” !=”的结果,即select * from a_test a inner join b_test b on a.id != b.id
select * from a_test a left outer join b_test b on a.id != b.id
select * from a_test a right join b_test b on a.id != b.id
select * from a_test a full outer join b_test b on a.id != b.id
都是笛卡尔乘积(cross join)去除Inner Join的结果。11条记录
相当于笛卡尔乘积去除了left outer join与自身的交集(其实就是Inner Join结果),就是left outer join的否定部分。
结果:
2 a22222 a222222 1 b11111 01
3 a33333 a333333 1 b11111 01
2 a22222 a222222 1 b11111 02
3 a33333 a333333 1 b11111 02
1 a11111 a111111 2 b22222 01
3 a33333 a333333 2 b22222 01
1 a11111 a111111 2 b22222 02
3 a33333 a333333 2 b22222 02
1 a11111 a111111 4 b44444 01
2 a22222 a222222 4 b44444 01
3 a33333 a333333 4 b44444 01
《3》多个表可以用 select * from table1 left join table2 on 条件1 left join table3 on 条件2 left join table4 on 条件3 where 条件4 的形式写。
总结:
CrossJoin结果集合:笛卡尔乘积A
InnerJoin结果集合:B
LeftJoin结果集合:C
RightJoin结果集合:D
FullJoin 结果集合:E
则A不等于B+C+D+E。 B真包含于A 、C、D、E,A 、C、D、E等于B加上Null的记录。C、D、E不包含于A。C、D、E的否定都等于A减去B,或说都等于A减去A于他们的交集。
+++
- 说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)
方法一:select * into b from a where 1<>1
方法二:select top 0 * into b from a
注意:复制的新表中的所有字段都将没有默认值,即使源表中有设默认值
- 说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)
insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件
例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where.. - 说明:显示文章、提交人和最后回复时间
select a.title,a.username,b.adddate from a,(select max(adddate) adddate from table,a where table.title=a.title) b - 说明:两张关联表,删除主表中在副表中没有的信息
delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )
注意:
若将
select * from table2 where table1.field1=table2.field1
改为
select * from table1,table2 where table1.field1=table2.field1
多了一个table1
则删除不成功
- 说明:日程安排提前五分钟提醒
select * from 日程安排 where datediff(mi,开始时间,getdate())>5
- 说明:一条sql 语句搞定数据库分页
select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段
- 说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)
select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b) - 说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表
(select a from tableA ) except (select a from tableB) except (select a from tableC) - 说明:随机取出10条数据
select top 10 * from tablename order by newid() - 说明:随机选择记录
select newid() - 说明:删除重复记录
Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...) - 说明:列出数据库里所有的表名
select name from sysobjects where type='U' - 说明:列出表里的所有的
select name from syscolumns where id=object_id('TableName') - 使用SQL语句 用...代替过长的字符串显示
语法:
SQL数据库:select case when len(field)>10 then left(field,10)+'...' else field end as news_name,news_id from tablename
Access数据库:SELECT iif(len(field)>2,left(field,2)+'...',field) FROM tablename; - --获得当月最后一天,时间全是0,如:2007-09-30 00:00:00.000
select dateadd(dd,-1,dateadd(mm,datediff(mm,0,dateadd(mm,1,getdate())),0))
--获得当月最后一天,时间为当前时间,如:2007-09-30 12:07:37.030
select dateadd(dd,-1,dateadd(mm,1,getdate()-day(getdate())+1))
--获得当月天数,如:30
select datediff(dd,getdate()-day(getdate())+1,dateadd(mm,1,getdate()-day(getdate())+1))
+++ -
Access2000 使用SQL语句联接表2007-10-20 19:31使用SQL语句联接表
在SQL中,很多威力都来自于将几个表或查询中的信息联接起来,并将结果显示为单个逻辑记录集的能力。在这种联接中包括INNER、LEFT、RIGHT这三种JOIN操作。
首先我们来讲讲INNER JOIN 的用法:INNER JOIN 语句可以用来组合两个表中的记录,只要在公共字段之中有相符的值即可,在语法上,INNER JOIN 是这样定义的。举个例子:我们现在要将“图书资料表”和“出版社资料表”联接起来,然后列出出版社所出的图书。让我们先看看这两个表,
然后在SQL设计视图中输入以下内容
现在我们执行这个SQL语句,
发现现在的查询结果将所有出版社和图书都列了出来。
这个查询好像也可以用下面的语句来实现。将两个查询都切换到数据表视图后我们会发现两个查询的查询结果虽然一样,但在使用INNER JOIN操作的查询中可以添加新的数据。就像在表中添加数据一样。而没有使用INNER JOIN 操作的查询就不能添加新数据,相比之下使用INNER JOIN操作的查询更像将两个具有相关内容的表联接在一起新生成的表。
知道了它的用处,我们来看看LEFT JOIN 的结构:
FROM [表名1] LEFT JOIN [表名2]
ON [表名1.字段A] 〈关系运算符〉[表名2.字段B]
其实LEFT JOIN 的功能就是将LEFT左边的表名1中的所有记录全部保留,而将右边的表名2中的字段B与表名1.字段A相对应的记录显示出来。而RIGHT JOIN 和LEFT JOIN 相反。
所以刚才的那个例子还可以写成:单击工具栏上的“执行”按钮,我们看到这时显示的数据表和刚才显示的用LEFT JOIN 的数据表一样。现在看出来了吧,原来它们的功能是可以互换的。
如果想将几个表联接起来,在JOIN操作中我们可以进行嵌套操作,有三个表:表1、表2、表3,现在将三个表联接起来:
FROM (表1 INNER JOIN 表2 ON 表1.序号=表2.序号)
INNER JOIN 表3
ON 表1.序号=表3.序号
这样这三个表就联接起来了。
ACCESS中的"Case...When" 用iif()函数
例如: select iif(aa="a","字母a",iif(aa="b","字母b,"其他")) from 表