posts - 188,comments - 176,trackbacks - 0

有关数据库的一写操作:
创建表项就不说了.
CREATE   TABLE  Student
    (Sno CHAR(5) NOT NULL UNIQUE,
     Sname CHAR(20),
     Ssex CHAR(1),
     Sage INT,
     Sdept CHAR(15));
插入记录:
insert into Student (Sno,Sname,Ssex,Sdept) values('aaa','mary','f','172');
删除记录:
delete from Student where Sno = 'aaa';
注:只需要删除一个主键就可以了。其他的记录会相应的删除掉。
删除表中一个字段:
ALTER  TABLE  Student DROP column Ssex; 列名;
修改表中的那一行数据:
原来的记录:
Sno  Sname  Ssex  Sdept
aaa  mary    f     172
update Student set Sname='mary1', Ssex='m' where Sno='aaa';
修改后:
Sno  Sname  Ssex  Sdept
aaa  mary1    m     172


desc倒叙排列:
建立索引:
create unique index Sno on Student(Sno);
索引的一点好处:在查询时候比较方便,在存在的所有记录中查找一个Sno=1的时候!建立索引的表中就直接查找Sno项比较它是否=1找到后查相关的记录就比较快。没有建立索引的需要把所有信息都查找一遍,再在其中找Sno字段,再比较其值=1的相关记录。

默认是ASC。
按表中哪个字段倒叙排序:
select * from Student order by Sno desc;
注意:要排序的字段必须是int型。

设置成自增长的字段在插入数据的时候不需要插入该字段的值:
select * from Student order by Sno desc;
原来没有设置成自增长插入数据命令:
insert into Student (Sno,Sname,Ssex,Sdept) values('aaa','mary','f','172');
将int型的Sno字段设置成自增长后
insert into Student (Sname,Ssex,Sdept) values('mary1','f','172');
insert into Student (Sname,Ssex,Sdept) values('mar1y','f','172');
insert into Student (Sname,Ssex,Sdept) values('ma1ry','f','172');
insert into Student (Sname,Ssex,Sdept) values('m1ary','f','172');

在表中的排序如下:
Sno   Sname  Ssex  Sdept
1     mary1   f     172
2     mar1y   f     172
3     ma1ry   f     172
4     m1ary   f     172
/*********************************************************************************
2006.7.20
*********************************************************************************/
查询表中记录总数:(无字段名字)
select count() from usertable;
或:(userid 为字段名字,结果是字段的总行数)
select count(*) userid from Student;

查询字段的平均值:
selecet avg(Sno) from Student;
select avg(字段名)from 表名;

给出查询的字段的平均值取别名:
select avg(字段名) as (别名) from (表名);

查找指定的字段的其他字段
select Sdept,Ssex,Sname
from Student
where Sno=3;
(where Sname='mary1';或则where Sname like 'mary1';)

在between语句查询的都是在and之间的所有值而IN语句则必须是in括号里面的值.
select Sno,Ssex,Sname from Student  where Sdept between 180 and 190;

select Sno,Ssex,Sname  from Student  where Sdept  in (172,190);

查询Student表中的所有的名字中的Sno和Ssex值.
select Sno,Ssex from Student  where Sdept >= 170 and Sname like '%%';
注:%%之间是把所有的String类型的值


like和where条件查询
select last_name,salsry,department_id from employees where last_name like 'G%' and salary>3000;

查询Student表中的所有的名字中间有mary的所有名字对应的的Sno和Ssex值.
select Sno,Ssex from Student  where Sdept >= 170 and Sname like '%mary%';
注:mary1,1mary,marydsajdh,等.

注意:and or not 用的时候,and是用在连接并列条件的2个不同的字段
or是用在选择的2个不同的字段之间,not一般用于not in(180,190)之间.
order by 和asc|desc的一点不同:
order by是按先进先排,desc是先进后排,asc和desc是排列顺序不一样.



disctinct条件查询
distinct 这个关键字来过滤掉多余的重复记录只保留一条,

select distinct name from table 表示将返回table表中name字段不重复的所有字段的集合。

注:distinct必须放在开头,select id distinct name from table 是错误的!

-------------------------------------------------------------------------------------
表TEST_1:
id         name1         name2   
9         aaa                11
8         bbb               22
3         ccc                33
4         ccc                44   
5         bbb               55
6         ddd               66
7         eee                77
-------------------------------------------------------------------------------------

select distinct(name1) from test_1 

结果:
name1
aaa
bbb
ccc
ddd
eee
distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的集合,而不是用它来返回不重记录的所有值。其原因是distinct只能返回它的目标字段,而无法返回其它字段,即上表中只能返回name1字段的所有不重复记录集合。

-------------------------------------------------------------------------------------
如果现在想查询出表test_1中所有name1不重复的id和name1字段的记录呢?

select distinct name, id from table

结果:
name1     id
aaa           9   
bbb          5
bbb          8
ccc           3
ccc           4
ddd          6
eee           7

并不是我们所想要的结果

select distinct name,id  from table 作用了两个字段,也就是必须得id与name都相同的才会被排除,即返回去除table表中id和name两个字段同时相同情况下所有集合。
-------------------------------------------------------------------------------------

如果现在想查询出表test_1中所有name1不重复的所有字段的记录呢?

对于
select   *   from   test_1 where   name1   in   (select   distinct   name1  from   tablename) 
等价于
select   *   from   test_1 where   name1   in   ('aaa','bbb','ccc','ddd','eee')
我们很可能认为它是可行的,但实际上结果却是:

id         name1         name2   
9         aaa                11
8         bbb               22
3         ccc                33
4         ccc                44   
5         bbb               55
6         ddd               66
7         eee                77

正确sql应该是:
select *  from test_1 inner join (select  min(id)  as  id  from  test_1  group  by  name1 order by id )  T  on  test_1.id = T.id

min(id)或max(id)都行,order by id 可要可不要.这里用内连接实现联合查询,也可以用where语句

select *  from test_1 ,(select  min(id)  as  id  from  test_1  group  by  name1 order by id )  where   test_1.id = T.id

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

**********************************************************************************
                                     联合查询
**********************************************************************************
查询表中的各个字段的值
select Sno,Sname,Ssex,Sdept from Student;

多表查询(2个表,publishtable和publishtable,给表起了别名)
select u.userid,u.age,u.username,p.publishname from usertable u,publishtable p where u.userid = p.publishid;

多表查询(3个表employees,departments和locations表,给表起别名)
(从多表中查询出所有姓smith的雇员的名字,所在部门以及部门所在的城市)
select e.first_name,e.last_name,d.department_name,l.city from employees e,departments d,locations l where e.department_id = d.department_id and d.location_id = l.location_id and e.last_name = 'smith';


***********************************************************************************
                                     联合查询
***********************************************************************************

等值连接
/*将books表和表bookstype中的信息联合查询,条件是联系键相等*/
select * from books,bookstype where bookstype.typeid = books.typeid


内连接
/*将books表和表bookstype中的信息联合查询,条件是联系键相等,和等值连接等价*/
select * from books inner join  bookstype on books.typeid = bookstype.typeid

左外连接

/*将books表和表bookstype中的信息联合查询,包括在books表中没有和bookstype表关联的信息*/
select * from books left outer join bookstype on bookstype.typeid = books.typeid

右外连接

/*将bookstype表和books表中的信息联合查询,包括在bookstype表中没有和books表关联的信息*/
select * from books right outer join bookstype on bookstype.typeid = books.typeid

全连接

/*将bookstype表和books表中的信息联合查询,包括在books表中没有和bookstype表关联的信息以及在bookstype表中没有和books表关联的信息*/

select * from books full outer join bookstype on bookstype.typeid = books.typeid


不等值连接查询
/*两表关联查询,查询表A的cid在表B中没有对应cid的表A的信息SQL*/
SQLServer:
select * from mvc_catalog c where c.cid not in (select m.cid from mvc_book m);

ORACLE:
select * from mvc_catalog c where not exists (select m.cid from mvc_book m where m.cid = c.cid);


备注:在oracle中
左外连接也可以写为:
select * from books b,bookstype c where b.cid = c.cid(+)
右外连接可以写为:
select * from books b,bookstype c where b.cid(+) = c.cid

***********************************************************************************
                                     联合查询
***********************************************************************************
多表查询应该注意的几点:
多表查询和单表查询的不同在于多表查询在查询某个字段的时候应该带上表名
格式是:表名.字段名,表名.字段名
select bbs.id,bbs.name,bbs.dep,bbsr.id,bbsr.name
from bbs,bbsr
where bbs.id=bbsr.id;
一般的在多表查询中的表名取的麻烦用别名来代替
如下:
select b.id,b.name,b.dep,c.id,c.name
from bbs as b ,bbsr as c // from bbs b,bbsr c***注意取别名也可以用空格或则用as.
where b.id=c.id;

*************************************************************************************
                                    分组查询
*************************************************************************************

在select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。group by 子句可以将查询结果分组,并返回行的汇总信息SQLServer 按照group by 子句中指定的表达式的值分组查询结果。

-------------------------------------------------------------------------------------
分组查询一般是用来进行统计需求的,要进行分组查询必须使用group by子句或having子句,在分组统计时要用到SQL的多行存储函数。在where条件中不能使用多行存储函数.

查询语句的select 和group by ,having 子句是聚组函数唯一出现的地方,在where 子句中不能使用聚组函数。

在带有group by 子句的查询语句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数.
------------------------------------------------------------------------------------

部门表department:

department_id    department_name
10                        开发部
20                        测试部
30                        用服部
40                        财务部
50                        培训部

雇员表employees:(department_id为外键)

id     employees_name   department_id
1      cheng                     10
2      zhou                       50
3      liguo                       10 
4      wang                      20
5      feng                        30
6      ling                         30
7      wu                          20 
8      tang                        20
9      yang                        40
10    tan                          50
------------------------------------------------------------------------------------

按部门编号统计出表employees中的每个部门的人数(group by分组查询)
select department_id, count(*) from employees
group by department_id;

显示出部门人数少于5人的部门编号以及人数( 按照department_id来分组,having count(*)<5做为限制条件 )
select department_id 部门号, count(*) 部门人数 from employees
group by department_id
having count(*)<5;
--------------------------------------
(注意:having必须在group by子句的后面)
--------------------------------------
图:
    部门号       部门人数
------------------------------
     10            2
     20            3
     30            2
     40            1    
     50            2
-------------------------------------------------------------------------------------
where子句和having子句可以同时使用,where子句是对要分组的行进行过滤,即选择要分组的行;
而having子句是对分组后的数据进行过滤。此时where子句必须在group by...having子句之前
-------------------------------------------------------------------------------------
显示出所有工资大于5000,且部门人数大于5个的部门号,部门最低工资和部门人数

select department_id 部门号(记住department_id 和部门号之间要空格), min(salary) 最低工资,count(*) 部门人数 from employees
where salary >5000
group by department_id
having count(*)>5;

图:
--------------------------------------
    部门号      最低工资      部门人数
    80          6100          34 
    100         6800          6 

group by 按照哪个字段来排序查询,一般的group by和having一起使用,注意在查询中只能查询与group by和having有关的字段。
--------------------------------------

  where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。

  having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组

  查询每个部门的每种职位的雇员数(待测试...)
  select deptno,job,count(*) from emp group by deptno,job;



*********************************************************************************
                                  数据排序
*********************************************************************************

order by子句中可以用asc(升序)和desc(降序)来完成相应的排序,默认时是按找asc(升序)。
---------------------------------------------------------------------------------
显示出所有工资大于5000,且部门人数大于5个的部门号,部门最低工资和部门人数,并要求按照部门人数降序排序.

select department_id 部门号(记住department_id 和部门号之间要空格), min(salary) 最低工资,count(*) 部门人数 from employees
where salary >5000
group by department_id
having count(*)>5
order by count(*)desc
-------------------------------------------------------------------
(注意:当对分组查询后的结果进行排序时,order by 必须在group by之后)
-------------------------------------------------------------------

图:
--------------------------------------
    部门号      最低工资      部门人数
    80          6100          34 
    100         6800          30 
    90          6500          28
    70          6300          25

*******************************************************************************
                                      子查询
*******************************************************************************

-----------------------------------------------------------------------------------------------------
子查询是一个在select查询中含有其他的select语句,子查询通常用在where子句中,即将一个查询结果做为查询的条件.
-----------------------------------------------------------------------------------------------------
统计表employees中所有工资小于平均工资的人数
select count(*)工资 from employees
where salary <
(select avg(salary) from employees)
图:
----------------
   工资
   56
   49
   36

Select MIN(Salary),Manager_id
from Employee
group by Manager_id
having MIN(Salary) >
                    (Select MIN(Salary)
                     From Employee
                     where Manager_id=004);

注意在多表查询中返回的值应该是一个唯一确定的值,而不应该是多中值。
select Employee_id,Last_name,Salary,Manager_id
from Employee
WHERE Salary>
                 (select Salary
                  from Employee
                  where Manager_id=003)
and 
     Last_name=  (select Last_name
                  from Employee
                  where Last_name like 'mary');

注意在any,or,all的区别:
Select Salary,Manager_id,Last_name,Employee_id
from Employee
where Salary < any
                    (Select Salary
                     From Employee
                     where Manager_id=005);

Select Salary
                     From Employee
                     where Manager_id=005;返回的是2000,2500
就是在工资中小于2000.2500其中一个就可以了,而ALL则必须是小于2000和2500其中任何一个
。而or则是和and用在一起的.

******************************************************************************************
                                        集合运算
******************************************************************************************

---------------------------------------------------------------------------------
集合运算是将2个或多个子查询结果进行(并union),交(intersect)和减(minus)
---------------------------------------------------------------------------------
(并union):
select employee_id,empname from emp1
union
select employee_id,name from emp2

图:
-----------------
employee_id       empname
100                    king1
1000                  king2
1000                  king3
10000                king4
100000              king5
1000000            king6
  
注:使用union,重复行只包括一个,当使用union all时将包括重复行

交(intersect):2个或多个子查询的公共行
select employee_id,empname from emp1
intersect
select employee_id,name from emp2

减(minus):从第一个查询结果中去掉出现在第二个查询结果中的行:
select employee_id,empname from emp1
minus
select employee_id,name from emp2


*****************************************************************************************
                             视图,存储过程和触发器
*****************************************************************************************

创建视图:(查询数据,用于系统统计报表)
create view dept_sum_vu
   (name,minsal,maxsal,avgsal)
as select d.department_name,min(e.salary),max(e.salary),avg(e.salary)
   from employees e,departments d
where e.department_id = d.department_id
group by d.department_name;

存贮过程,触发器和删除外键

1).存贮过程:
存贮过程的路径:打开Stored Procedures中new一个新的Stored Procedures,中间填写代码,代码如下:
CREATE PROCEDURE sa.bbsTest AS

select  Bbsid ,content , area_id , name  FROM BBs  a  JOIN   bbs_area  b
on a.area_id =  b.id


CREATE PROCEDURE bbsTest  AS

select  Bbsid ,content , area_id , name  FROM  BBs  a  JOIN   bbs_area  b
on a.area_id =  b.id

2).触发器

打开用户表项,点设计表,选中其中一个字段,右键task点manager triggers,在弹出的表单中写代码:
CREATE TRIGGER [tD_bbs_area] ON [dbo].[bbs_area]
FOR  DELETE
AS
BEGIN
 DELETE rebbs
 FROM  bbs, deleted
 WHERE rebbs.bbs_id = bbs.bbsid
       AND bbs.area_id = deleted.id

 DELETE bbs
 FROM  deleted
 WHERE bbs.area_id = deleted.id

END

3).删除外键
打开用户表项,点设计表,选中其中一个字段,右键relationships,在弹出的主键和外键中选择就可以了.
删除外键,需要先删除主键表里面的有关外键的字段,再来删除外键的有关字段.




 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2007-05-24 11:40 cheng 阅读(3922) 评论(0)  编辑  收藏 所属分类: SQLServer

只有注册用户登录后才能发表评论。


网站导航: