SQL基础知识总结(一)

1.join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接

内连接(INNER JOIN)

内连接分三种:

  等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。
  不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、、!。
  自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列

外连接

分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行

 外连接内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件
的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。

如下面使用左外连接将论坛内容和作者信息连接起来:
代码:SELECT a.*,b.* FROM `luntan` LEFT JOIN usertable as b
ON a.username=b.username

下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:
代码:SELECT a.*,b.*
FROM city as a FULL OUTER JOIN user as b
ON a.username=b.username

交叉连接(CROSS JOIN)

没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

 2.内连接、外连接和交叉连接三者区别

内连接就是左表和右表相同的数据
外连接分为:左外连接、右外连接、全外连接,左外连接就是以左表为准,去匹配右表,左表有多少条数据,结果就是多少条数据右外连接就是与左外连接反之,以右表为准,去匹配左表,右表有多少条数据,结果就是多少条数据交叉连接,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

3.如果你不给DELETE 语句提供WHERE 子句,表中的所有记录都将被删除。如果你想删除应该表中的所有记录,用TRUNCATE TABLE 语句代替DELETE语句。

1、TRUNCATE在各种表上无论是大的还是小的都非常快。如果有ROLLBACK命令Delete将被撤销,而TRUNCATE则不会被撤销。 
2、TRUNCATE是一个DDL语言,向其他所有的DDL语言一样,他将被隐式提交,不能对TRUNCATE使用ROLLBACK命令。
3、TRUNCATE将重新设置高水平线和所有的索引。在对整个表和索引进行完全浏览时,经过TRUNCATE操作后的表比Delete操作后的表要快得多。
4、TRUNCATE不能触发任何Delete触发器。
5、当表被清空后表和表的索引讲重新设置成初始大小,而delete则不能。
6、不能清空父表。

在oracle里,使用delete删除数据以后,数据库的存储容量不会减少,而且使用delete删除某个表的数据以后,查询这张表的速度和删除之前一样,不会发生变化。

因为oralce有一个HWM高水位,它是oracle的一个表使用空间最高水位线。当插入了数据以后,高水位线就会上涨,但是如果你采用delete语句删除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水位。除非使用truncate删除数据。那么,这条高水位线在日常的增删操作中只会上涨,不会下跌,所以数据库容量也只会上升,不会下降。而使用select语句查询数据时,数据库会扫描高水位线以下的数据块,因为高水位线没有变化,所以扫描的时间不会减少,所以才会出现使用delete删除数据以后,查询的速度还是和delete以前一样。
4.COPY

INSERT 语句与DELETE语句和UPDATE语句有一点不同,它一次只操作一个记录。然而,有一个方法可以使INSERT 语句一次添加多个记录。要作到这一点,你需要把INSERT 语句与SELECT 语句结合起来,象这样:
复制内容到剪贴板
代码:INSERT mytable (first_column,second_column)
SELECT another_first,another_second
FROM anothertable
WHERE another_first=’Copy Me!’ 这个语句从anothertable拷贝记录到mytable.只有表anothertable中字段another_first的值为’Copy Me!’的记录才被拷贝。
当为一个表中的记录建立备份时,这种形式的INSERT 语句是非常有用的。在删除一个表中的记录之前,你可以先用这种方法把它们拷贝到另一个表中。
如果你需要拷贝整个表,你可以使用SELECT INTO 语句。例如,下面的语句创建了一个名为newtable的新表,该表包含表mytable的所有数据:
复制内容到剪贴板
代码:SELECT * INTO newtable FROM mytable 你也可以指定只有特定的字段被用来创建这个新表。要做到这一点,只需在字段列表中指定你想要拷贝的字段。另外,你可以使用WHERE 子句来限制拷贝到新表中的记录。下面的例子只拷贝字段second_columnd的值等于’Copy Me!’的记录的first_column字段。
复制内容到剪贴板
代码:SELECT first_column INTO newtable
FROM mytable
WHERE second_column=’Copy Me!’ 使用SQL修改已经建立的表是很困难的。例如,如果你向一个表中添加了一个字段,没有容易的办法来去除它。另外,如果你不小心把一个字段的数据类型给错了,你将没有办法改变它。但是,使用本节中讲述的SQL语句,你可以绕过这两个问题。
例如,假设你想从一个表中删除一个字段。使用SELECT INTO 语句,你可以创建该表的一个拷贝,但不包含要删除的字段。这使你既删除了该字段,又保留了不想删除的数据。
如果你想改变一个字段的数据类型,你可以创建一个包含正确数据类型字段的新表。创建好该表后,你就可以结合使用UPDATE语句和SELECT 语句,把原来表中的所有数据拷贝到新表中。通过这种方法,你既可以修改表的结构,又能保存原有的数据。

5date  

包含了 年份、月份、日期。  
time  
包含了 小时、分钟、秒。  
timestamp  
包含了 年、月、日、时、分、秒、千分之一秒。

6.整合性的查询

Select SUM(column1)  
FROM table_name  
说明:  
1.计算出总和,所选的栏位必须是可数的数字形态。  
2.除此以外还有 AVG() 是计算平均、MAX()、MIN()计算最大最小值的整合性查询。  
Select column1,AVG(column2)  
FROM table_name  
GROUP BY column1  
HAVING AVG(column2) 〉 xxx  
说明:  
1.GROUP BY: 以column1 为一组计算 column2 的平均值必须和 AVG、SUM等整合性查询的关键字  
一起使用。  
2.HAVING : 必须和 GROUP BY 一起使用作为整合性的限制。

7.删除重复记录


Delete from tablename where id not in (select max(id) from tablename group by col1,col2,…)

8.选择从10到15的记录

select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc

9.select city,count(*),min(birth_day) from customer group by city having count(*)>10″;

这句话是先按city归组,然后找出city地数量大于10的城市

10.为什么要使用视图(View)

使用视图将会得到如下好处:

视图隐藏了底层的表结构,简化了数据访问操作。因为隐藏了底层的表结构,所以大大加强了安全性,用户只能看到视图提供的数据使用视图,方便了权限管理,让用户对视图有权限而不是对底层表有权限进一步加强了安全性。

11.索引

为什么要创建索引呢?这是因为,创建索引可以大大提高系统的性能。

第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

第二,可以大大加快 数据的检索速度,这也是创建索引的最主要的原因。

第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

第四,在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

增加索引也有许多不利的一个方面。

第一,创建索引和维护索引要耗费时间,这种时间随着数据 量的增加而增加。

第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

创建索引的方法和索引的特征

创建索引的方法

创建索引有多种方法,这些方法包括直接创建索引的方法和间接创建索引的方法。直接创建索引,例如使用CREATE INDEX语句或者使用创建索引向导,间接创建索引,例如在表中定义主键约束或者唯一性键约束时,同时也创建了索引。虽然,这两种方法都可以创建索引,但 是,它们创建索引的具体内容是有区别的。

使用CREATE INDEX语句或者使用创建索引向导来创建索引,这是最基本的索引创建方式,并且这种方法最具有柔性,可以定制创建出符合自己需要的索引。在使用这种方式 创建索引时,可以使用许多选项,例如指定数据页的充满度、进行排序、整理统计信息等,这样可以优化索引。使用这种方法,可以指定索引的类型、唯一性和复合 性,也就是说,既可以创建聚簇索引,也可以创建非聚簇索引,既可以在一个列上创建索引,也可以在两个或者两个以上的列上创建索引。

通过定义主键约束或者唯一性键约束,也可以间接创建索引。主键约束是一种保持数据完整性的逻辑,它限制表中的记录有相同的主键记录。在创建主键约束时,系 统自动创建了一个唯一性的聚簇索引。虽然,在逻辑上,主键约束是一种重要的结构,但是,在物理结构上,与主键约束相对应的结构是唯一性的聚簇索引。换句话 说,在物理实现上,不存在主键约束,而只存在唯一性的聚簇索引。同样,在创建唯一性键约束时,也同时创建了索引,这种索引则是唯一性的非聚簇索引。因此, 当使用约束创建索引时,索引的类型和特征基本上都已经确定了,由用户定制的余地比较小。

 当在表上定义主键或者唯一性键约束时,如果表中已经有了使用CREATE INDEX语句创建的标准索引时,那么主键约束或者唯一性键约束创建的索引覆盖以前创建的标准索引。也就是说,主键约束或者唯一性键约束创建的索引的优先 级高于使用CREATE INDEX语句创建的索引。

12。序列

 

序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字)。其主要的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值。创建序列需要CREATE SEQUENCE系统权限。

13.模式

 

模式(schema) 是用于 在一个 大项目中的 各个 小项目每个 小项目的表, 放在 各自的 模式(schema) 下面.这样, 遇到 小项目里面. 有 相同名字的 表的话,  不会发生冲突.

14. 需要注意 having 和 where 的用法区别

having 只能用在 group by 之后,对分组后的结果进行筛选(即使用 having 的 前提条件是分组)。

where 肯定在 group by 之前,即也在 having 之前。

where 后的条件表达式里不允许使用聚合函数,而 having 可以。

15当一个查询语句同时出现了 where,group by,having,order by 的时候, 执行顺序和编写顺序是:

    1.执行 where xx 对全表数据做筛选,返回第 1 个结果集。

   2.针对第 1 个结果集使用 group by 分组,返回第 2 个结果集。

  3.针对第 2 个结果集中的每 1 组数据执行 select xx,有几组就执行几次,返回  第 3 个结果集。

   4.针对第 3 个结集执行 having xx 进行筛选,返回第 4 个结果集。

   5.针对第 个结果集排序。 例子: 例子:

 

完成一个复杂的查询语句,需求如下:

按由高到低的顺序显示个人平均分在 70 分以上的学生姓名和平均分,为了尽可能地提高平均分,在计算平均分前不包括分数在 60 分以下的成绩,并且也不计 算"jr"的成绩。 

分析:

  1.要求显示学生姓名和平均分 因此确定第 1 步 select s_name,avg(score) from student

   2.计算平均分前不包括分数在 60 分以下的成绩,并且也不计算贱人(jr)的 成绩 因此确定第 2 步 where score>=60 and s_name!=’jr’

  3.显示个人平均分 相同名字的学生(同一个学生) 相同名字的学生(同一个学生)考了多门科目 因此按姓名分组 确定第 3 步 group by s_name

  4.显示个人平均分在 70 分以上 因此确定第 4 步 having avg(s_score)>=70

  5.按由高到低的顺序 因此确定第 5 步 order by avg(s_score) desc

16.命令行导入sql脚本(防止乱码)

/usr/local/webserver/mysql/bin/mysql -h localhost -u root -p --default-character-set=utf8 seachdeviec_db<seachdeviec.sql;

17.//查询出重复了的列的值

select name from accp.first group by name having count(name)>2;

18.//查询出所有的重复的列

select name from accp.first where name in (select name from accp.first group by name having count(name)>3)

19.子查询

 

  --1.in :可以用来检查在一个值列表中是否包含指定的值。这个值列表也可以来自一个子查询的返回结果。

 

  --2.any :用来将一个值与一个列表中的"任何值"进行比较。在查询中any操作之前,必须使用一个=,>,>=等比较操作符。

 

  select id from userinfo where uid= any(select id from product);

 

  --3.all :用来将一个值与一个列表中的"所有值"进行比较。在查询中all操作之前,必须使用一个=,>,>=等比较操作符。

 

select id from userinfo where uid= all(select id from product);

 

  --4.Exists :用于检查子查询所返回的行的存在性。用在select语句中。

 

  由于Exists只检查子查询返回的行的存在性,因此查询不必返回一列,可以返回一个学量值(1).

 

    示例:用not exists检索从来未曾被购买过的产品

 

        select product_id,name from product outer

 

          where not exists (select 1 from purchases inner

 

          where inner.product_id=outer.product_id);

 

  --5.比较Exists和In之间的区别

 

  Exists与In不同:Exists只检查行的存在性,而In则要检查实际值的存在性.

in 和 exists也是很好区别的. in 是一个集合运算符. a in {a,c,d,s,d....} 这个运算中,前面是一个元素,后面是一个集合,集合中的元素类型是和前面的元素一样的. 而exists是一个存在判断,如果后面的查询中有结果,则exists为真,否则为假. in 运算用在语句中,它后面带的select 一定是选一个字段,而不是select *. 比如说你要判断某班是否存在一个名为"小明"的学生,你可以用in 运算: "小明" in (select sname from student) 这样(select sname from student) 返回的是一个全班姓名的集合,in用于判断"小明"是否为此集合中的一个数据; 同时,你也可以用exists语句: exists (select * from student where sname="小明")

 

  通常来讲,Exists比In的性能要高,应尽可能使用Exists.

 

  Not Exists与Not In的查询区别:

 

  

1、对于not exists查询,内表存在空值对查询结果没有影响;对于not in查询,内表存在空值将导致最终的查询结果为空。

2、对于not exists查询,外表存在空值,存在空值的那条记录最终会输出;对于not in查询,外表存在空值,存在空值的那条记录最终将被过滤,其他数据不受影响。

 

   示例:not exists

 

     select product_type_id,name from product_type_id outer

 

       where not exists (select 1 from products inner

 

         where inner.product_type_id=outer.product_type_id)

 

    这个查询是有结果的.正常情况下,products产品表中不定有所有的产品类型的产品.所以这个本应是无结果.

 

    示例:not in

 

      select product_type_id,name from product_type_id

 

       where product_type_id not in (select produt_type_id from        products )

面试题

员工基本信息表EMPINFO

 CREATE TABLE EMPINFO

 (

  EMP_ID  char(10)  PRIMARY KEY, 

 NAME  char(6) ,

 BIRTHDAY  date ,  

 SAL  number(4)     

 );

 

 积分表(INTEG)共有3个字段:

 CREATE TABLE INTEG

 (

 INTEGER_ID  char(10) PRIMARY KEY,

 HABITUDE  varchar2(10), 

 SCORE number(4)   

 );

 

积分情况表:

CREATE TABLE THING

 (

EMP_ID  char(10), 

 INTEGER_id  char(10)

 );

 

 

--1.1、     查询员工基本信息表中的所有信息。

select * from empinfo;

--2、查询员工基本信息表中所有员工的员工编号,姓名和薪水。

select EMP_ID as 员工编号,name as 姓名,SAL as 薪水 from empinfo;

--3、         查询所有员工的姓名,出生年月,并在出生年月前显示"出生日期"字串。

select NAME as 姓名,concat('出生日期',BIRTHDAY) as 出生年月 from empinfo;

--4、         查询员工基本信息表中的所有信息,要求列标题显示为中文。

select EMP_ID as 员工编号 ,NAME as 姓名,BIRTHDAY as 生日 ,SAL as 薪水 from EMPINFO;

--5、         查询员工基本信息表中姓名和加200后的薪水

select NAME as 姓名,(SAL+200) as 薪水 from empinfo;

--6、         查询员工基本信息表中姓名和负值薪水。

select name,sal from empinfo where sal<0;

--7、         查询员工基本信息表中姓名及提高5%后的薪水。

select name,sal*0.05+sal from empinfo;

select sal*1.05 from empinfo;

--8、查询员工基本信息表中姓名及一个月中每天的薪水。

select name,to_char((sal/30),'999.99') as sal from empinfo;

--9、查询积分表中的所有信息,要求输出格式为"XXX----XXX----XXX----XXX"。

select INTEGER_ID,'----'||HABITUDE as HABITUDE,'----'||SCORE as SCORE from INTEG;

--10、       查询员工基本信息表中薪水低于300员的所有员工信息。

select * from empinfo where sal<300

--11、       查询姓名是"王彪"的员工信息。

select * from empinfo where name='王彪';

--12、       查询薪水在300至600之间的员工信息。

select * from empinfo where sal between 300 and 600;

--13、查询出生年月在"1-5月-1983"至"31-12月-1986"之间的所有员工信息。

select * from empinfo where birthday between '1-5月-1983' and '31-12月-1986';

--上面的语句在Command windows(sql>---sql*plus)中是可以用的,这里是sql用下面的可以

select * from empinfo where birthday between to_Date('01-05-1983','DD-MM-YYYY') and to_Date('31-12-1986','DD-MM-YYYY');

--14、查询积分编号为"I_001"和"I_004","I_002"的所有信息。

select * from INTEG where INTEGER_ID='I_001' or INTEGER_ID='I_002' or INTEGER_ID='I_004';

--15、       查询所有姓王的员工信息。

select * from empinfo where name like '王%';

--16、       查询没有登记出生年月的员工信息。

select * from empinfo where birthday is null;

--17、       查询公司的薪水发放标准。

--18、       查询员工编号为iex_0001完成的积分总数

--这里要加上sum()函数,因为iex_0001的积分不只一次,是多次,所以查询要用in,结果用sum()

select sum(score) from integ where  INTEGER_ID in (select INTEGER_id from thing where EMP_ID='iex_0001');

--为什么会是7(两次4和3),3因为score类型number(4),没有小数点,而(第二次)2.5变成3

--19、查询习哲亮的所有信息,并把他的出生年月推迟一个月。

select emp_id,name,sal,add_months(birthday,-1) as birthday from empinfo where name='习哲亮';

--20、       查询习哲亮出生那个月的最后一天。这个结果是日期格式:yyyy-mm-dd

select emp_id,name,sal,last_day(birthday) as birthday from empinfo where name='习哲亮';

--20-1查询习哲亮出生那个月的最后一天是30天,还是31天,28天。日期格式是单数(天数)

select emp_id,name,sal,to_char(birthday,'DD') as birthday from empinfo where name='习哲亮';

select emp_id,name,sal,to_char(last_day(birthday),'DD') as birthday from empinfo where name='习哲亮';

------'DDD'一年中的第几天,'DD'一月中的第几天,'D'一周中的第几天

--21、       查询习哲亮出生有多少岁了。

select to_date(sysdate)-birthday from empinfo where name='习哲亮';

select to_char(sysdate,'YYYY')-to_char(birthday,'YYYY') from empinfo where name='习哲亮';

--22、查询习哲亮出生后的第一个星期四是几号。

select next_day(birthday,'星期四') from empinfo where name='习哲亮';

select to_char(next_day(birthday,'星期四'),'DD') from empinfo where name='习哲亮';

select next_day(to_date(sysdate),'星期四') from dual;--测试用

--23、       查询今天的日期。

select to_char(sysdate) as abc from empinfo ;

--24、       查询所有员工信息,按薪水的升序显示。

select * from empinfo order by sal;

select * from empinfo order by sal desc;--降序 --消除重复行distinct

--25、对员工基本信息表和积分情况表进行非限制连接查询员工编号,姓名,积分编号

select e.emp_id,e.name,t.INTEGER_id from empinfo e left join thing t on t.EMP_ID=e.emp_id;

select * from empinfo e left join thing t on t.EMP_ID=e.emp_id;

--26、       查询所有员工的姓名,所得的积分编号,按姓名升序显示。

select e.name,t.INTEGER_id from empinfo e full join thing t on e.emp_id=t.emp_id order by e.name;

--27、       查询薪水高于400的员工姓名及积分编号,按员工姓名升序,积分编号降序显示。

select  e.name,t.integer_id from empinfo e left join thing t on e.emp_id=t.emp_id

       where e.sal>400

       order by e.name asc,t.integer_id desc;

--28、       查询所有员工信息和这些员工的积分编号。因为有的员工有两个积分编号

select e.emp_id,e.name,e.birthday,e.sal,t.integer_id from empinfo e left join thing t on e.emp_id=t.emp_id;

--29、       查询所有员工信息和他们所有积分信息。

select e.emp_id,e.name,e.birthday,e.sal,i.INTEGER_ID,i.HABITUDE,i.score

       from  empinfo e,thing t,integ i where e.emp_id=t.emp_id and

       t.integer_id=i.integer_id

 union

 select e.emp_id,e.name,e.birthday,e.sal from empinfo e left join thing t

 on e.emp_id=t.emp_id;

--以上只能找到匹配(empinfo与THING)内容,而empinfo中有的员工没有积分表的信息

-则没有显示.如果用Left可以但不能三表连接.left只有二表连接

 

--30、       查询薪水高于500元的员工姓名,原薪水,及薪水提高10%后的新薪水。

select name,sal,sal+sal*01 from empinfo where sal>500;

--31、       查询已得到积分编号=I_001的所有员工的信息。

select e.emp_id,e.name,e.BIRTHDAY,e.sal from empinfo e where e.emp_id in (select t.emp_id from thing t where t.integer_id='I_001') ;

--32、       查询除了习哲亮和王彪以外的所有员工信息。

select emp_id,name,birthday,sal from empinfo where name <> '习哲亮' and name <> '王彪';

select emp_id,name,birthday,sal from empinfo where name not like '习哲亮' and name not like '王彪';

--33、       查询所有的积分编号。

select * from thing ;

select * from integ;

--34、查询尚未得到任何积分的所有员工信息。

select emp_id,name,birthday,sal from empinfo where emp_id not in (select emp_id from thing);

--35、       在积分情况表上建立外键, THING.emp_id参照EMPINFO.emp_id

alter table thing add constraint thing_emp_id_fk foreign key (emp_id) references  empinfo(emp_id);

--36、       在员工基本信息表中为字段NAME建立唯一约束.

alter table empinfo add constraint empinfo_name_unique unique (name);

select * from empinfo;

insert into empinfo values('11','王彪',to_date('1938-5-9','YYYY-MM-DD'),500);

--37、       在员工基本信息表中建立检查约束,字段员工编号大于001和小于010的不允许插入.

alter table empinfo add constraint empinfo_id_ck emp_id between to_number(emp_id)>001 and emp_id<010;

--38、       将员工基本信息表中姓名为许丽丽的姓名更改为李丽丽.

update empinfo set name='李丽丽' where name='许丽丽';

select * from empinfo;

--39、       将员工基本信息表中编号为0008的员工删除.

delete from empinfo where emp_id='0008';

select * from empinfo;

rollback;

--40在员工基本信息表中创建名为员工信息表视图,只允许察看员工编号和员工姓名2个字段

create or replace view empinfo_view

       as

       select emp_id as 员工编号,name as 姓名 from empinfo;

select * from empinfo_view;

--41、查询40建立的视图

select * from empinfo_view;

--42、删除刚刚建立的视图.

drop view empinfo_view;

select * from empinfo_view;

--43在员工基本信息表中建立以员工姓名字段的索引,名为姓名字段索引。

create index index_empinfo_name on empinfo (name);

drop index index_empinfo_name;

create index 姓名 on empinfo(name);

 

--44、删除43建立的索引。

drop index 姓名;

--45、建立一个游标,循环提取员工信息表中所有name信息

declare

abc varchar2(10);

cursor empinfo_cursor is

       select name from empinfo;

begin

     for nameTemp in empinfo_cursor

     loop

         DBMS_output.put_line('员工姓名: '||nameTemp.name);

       -- select nameTemp.name from nameTemp;

       --如果要得到这个值只有给一个变量或变量数组

      --不行 select (nameTemp.name into abc) as dd from dual;

     end loop;

end;

---见:请按'OutPut'看结果.

--46,建立存储过程,将员工信息表中出生日期=11-5月-1984送入到定义的变量里。

create or replace procedure

       empinfoCheck(birTemp in date,bir out date)

       as

       empinfo_birthday date;

       begin

       select birthday into empinfo_birthday from empinfo where birthday=birTemp;

      -- DBMS_output.put_line('员工生日: '||empinfo_birthday);

         bir:=empinfo_birthday;

       end;

--运行存储过程empinfoCheck

declare

value2 date;

begin

   empinfoCheck(to_date('1984-5-11','YYYY-MM-DD'),value2);

   DBMS_output.put_line('员工生日: '||to_char(value2,'YYYY-MM-DD'));

end;

--47首先建立一个EMPINFO1结构和数据完全和EMPINFO一致,建立一个触发器,当向表EMPINFO插入一行数据之前,则向EMPINFO1表插入2个列,a列为变量,b列为常量.(a代表处发次数)

--1.建立empinfo1表,与empinfo表结构和数据一样

create table empinfo1 as select * from empinfo;

select * from empinfo1;

--2因为a代表触发次数,所以要建立一个序列

create sequence empinfo1_sequence

select * from user_sequences;

--3建立触发器

 

create or replace trigger empinfo_insert_trigger

      before insert or update of sal

      on empinfo

       for each row

      --where (new.sal<600) --触发器的条件,满足才触发

      begin

      --会报错,不能alter,如果把两行alter放在触发器外运行.触发器成功.47题有问题

       alter table empinfo1 add a varchar2(10);

       alter table empinfo1 add b varchar2(10);

      insert into empinfo1 values('iex_0008','河东',to_date('1986-8-9','YYYY-MM-DD'),650,empinfo1_sequence.nextval,'常量');

      end;

--测试触发器

select * from user_triggers;

insert into empinfo values('iex_0008','河东',to_date('1986-8-9','YYYY-MM-DD'),650);

select * from empinfo;

  

   alter table empinfo1 add a varchar2(10);--增加列

   alter table empinfo1 drop column a;--删除列

   select * from empinfo1;

 

--48分别创建用户TEMPUSER(UNLOCK)和角色temprole。

--(unlock表示未锁定)

--锁定account lock

create user TEMPUSER identified by accp account unlock;

--创建角色:没有创建角色的权限

create role temprole  identified by accp;

--要以system/accp用户连接数据库,本用户是datatest

grant create role to datatest;

create role temprole; --给角色设置密码identified by accp

--49、把能够创建任何表的权限给tempuser

grant resource to tempuser;

revoke resource from tempuser;

alter user tempuser identified by accp;--修改密码

--50、授权用户tempuser连接到数据库。

grant connect to tempuser

revoke connect from tempuser;

 

--51、       创建一个事务控制,就是实现汇总表上的示例的功能。

--group by分组汇总语句--rollup 跟在group by 后详细汇总

  select name,birthday,sum(sal) from empinfo group by birthday,rollup(name) having birthday='14-8月-1986'

--cube 实现总汇总 可以实现总汇总和单个明细汇总

  select name,birthday,sum(sal) from empinfo group by cube(name,biarthdy) --having birthday='14-8月-1986'

 

执行数据库查询时候,如果要查询的数据很多,假设有一千万条,用什么方法提高查询效率(速度)?在数据库方面或者java代码方面有什么办法?

  在数据库设计方面

  •   建立索引
  •   分区
  •   尽量使用固定长度字段
  •   限制字段长度
  •   在数据库I/o方面
  •   增加缓冲区
  •   如果涉及表的级联,不同的表存储在不同的磁盘上,以增加I/o速度。

  在sql语句方面

  • 优化sql语句,减少比较次数
  • 限制返回的条目数(mysql中用limit)

  在java方面

  如果是反复使用的查询,使用PreparedStaement ,减少查询次数。

 

Oracle由哪几部分组成:数据文件,控制文件,日子文件。

权限管理:任何人如果给予了这个权限都可以把权限授予其他人:grant …..on… to… with grant option

Group by(avg(salary ))是错误的,group by 语句不能包含avg(),min(),max()等这样的函数。

Any 、all 关键字可以把自查徐你的多行输出转换为单行的输出结果。Eg

Select distinct department_id from employees where salary>any(或者all)(

Slecte avg(salary) from employees group by department_id

)

Date 数据类型的列只能用count()和min()函数。

Sum()、avg()不能用在数据类型是date 的列上。、

 

 

posted @ 2013-04-30 21:47  西关大堤  阅读(189)  评论(0编辑  收藏  举报