數據庫面試題(一)子查詢及面試題練習


一、子查詢的基本理論

1.子查詢概念:

  • ()
  • 子查詢也叫做內部查詢,包含子查詢的語句稱為外部查詢或主查詢

2.子查詢的分類

  • 非相關子查詢  ---  用的最多
    • 子查詢的結果作為外部查詢的條件  
    • 子查詢的結果作為表
  • 相關子查詢(關聯)
    • 依賴於外部查詢的數據,外部查詢每執行一次,子查詢就執行一次
      • 外部查詢先查詢,在執行子查詢
    • 子查詢的結果作為列 

案例:

如:第一題,建表

drop table if exists tb_lemon_score;

create table tb_lemon_score( sname varchar(20), course varchar(20), score tinyint );

insert tb_lemon_score
values
    ( '張三', '語文', 71 ),
    ( '張三', '數學', 75 ),
    ( '李四', '語文', 76 ),
    ( '李四', '數學', 90 ),
    ( '王五', '語文', 81 ),
    ( '王五', '數學', 100 ),
    ( '王五', '英語', 90 );

查詢:查詢出每門課程都大於80分的學生姓名

方式一

select sname,score from tb_lemon_score group by sname having min(score)>80;

 

方式二:子查詢的結果作為外部查詢的條件 

先查詢出小於80的

select * from tb_lemon_score where sname not in (select sname from tb_lemon_score where score<=80);

 

方式三:子查詢的結果作為表

先查詢出每個人的最小成績,結果作為表,在查詢大於80分的學生

-- 每人的最小成績
select sname,min(score) 最小成績 from tb_lemon_score group by sname;
-- 在結果中查詢
select * from (select sname,min(score) 最小成績 from tb_lemon_score group by sname) t where t.最小成績>80;

 

方式四:相關子查詢(關聯)

  • 外部查詢先查詢,在執行子查詢
  • EXISTS :運算符用於判斷查詢子句是否有記錄,如果有一條或多條記錄存在返回 True,否則返回 False
  • not exists :EXISTS 可以與 NOT 一同使用,查找出不符合查詢語句的記錄:
select * from tb_lemon_score t1 where not exists 
(select * from tb_lemon_score t2 where t1.sname=t2.sname and t2.score<=80);

 

案例2:

#用sql語句查詢所有購入商品為兩種或兩種以上的購物人
-- 非關聯子查詢
SELECT sname FROM (SELECT sname,COUNT(merch) FROM shopping_list GROUP BY sname HAVING COUNT(merch)>=2) as list;
-- 關聯子查詢
SELECT DISTINCT sname FROM shopping_list s1 WHERE EXISTS 
    (SELECT * FROM shopping_list s2 WHERE s2.sname=s1.sname GROUP BY s2.sname HAVING COUNT(s2.merch)>=2)

 

面試題

1.查詢出所有語文成績超過平均水平的學生姓名、語文成績

-- 先兩條鏈接,1表id == 2表id  查詢后只有三條,and 語文成績大於平均成績
select s.name,sc.chinese from 表1 s,表2 sc 
where s.id = sc.id and sc.chinese > (select avg(chinese) from 表1);

-- 相當於 inner join  on
select s.name,sc.chinese from 表1 s inner join 表2 sc 
on s.id = sc.id and sc.chinese > (select avg(chinese) from 表1);

 

2.查詢出所有學生的姓名、語文成績

select s.name,sc.chinese from 學生表1 s left join 成績表2 sc on s.id = sc.id; 

======

-- 同上關聯子查詢,查詢結果作為列
select s.name,(select sc.chiinese from 成績表2 sc where 學生表.id = 成績表.id ) from 學生表1 s;

 兩條結果都相同 

 

3.導出所有語文或數學成績大於90分的學生信息到exce1中

select s.name,sc.chinese,sc.math from 學生表1 s,成績表2 sc 
where s.id = sc.id and (sc.math>=90 or sc.chinese>=90);

 

-- 非相關子查詢,結果作為一張表
select s.*,t.* from 學生表 s,(select sc.* from 成績表 sc where sc.math>90 or sc.chinese>=90) t where s.id = t.id;

 

練習題:

1.建表及數據

-- 部門表
-- CREATE TABLE DEPT( DEPTNO INT PRIMARY KEY, -- 部門編號 DNAME VARCHAR(14) , -- 部門名稱 LOC VARCHAR(13) -- 部門地址 ) ;
create table dept ( deptno int primary key, dname varchar ( 14 ), loc varchar ( 13 ) );

insert into dept
values
    ( 10, 'accounting', 'new york' );
insert into dept
values
    ( 20, 'research', 'dallas' );
insert into dept
values
    ( 30, 'sales', 'chicago' );
insert into dept
values
    ( 40, 'operations', 'boston' );


-- 員工表
-- CREATE TABLE EMP ( EMPNO INT PRIMARY KEY, -- 員工編號 ENAME VARCHAR(10), -- 員工名稱 JOB VARCHAR(9), -- 工作 MGR DOUBLE, -- 直屬領導編號 HIREDATE DATE, -- 入職時間 SAL DOUBLE, -- 工資 COMM DOUBLE, -- 獎金 DEPTNO INT, -- 部門號 FOREIGN KEY(DEPTNO) REFERENCES DEPT(DEPTNO));


create table emp (empno int primary key,ename varchar (10),job varchar (9),mgr double,hiredate date,sal double,comm double,deptno int,foreign key (deptno) references dept (deptno));

insert into emp
values
    ( 7369, 'smith', 'clerk', 7902, '1980-12-17', 800, null, 20 );
insert into emp
values
    ( 7499, 'allen', 'salesman', 7698, '1981-02-20', 1600, 300, 30 );
insert into emp
values
    ( 7521, 'ward', 'salesman', 7698, '1981-02-22', 1250, 500, 30 );
insert into emp
values
    ( 7566, 'jones', 'manager', 7839, '1981-04-02', 2975, null, 20 );
insert into emp
values
    ( 7654, 'martin', 'salesman', 7698, '1981-09-28', 1250, 1400, 30 );
insert into emp
values
    ( 7698, 'blake', 'manager', 7839, '1981-05-01', 2850, null, 30 );
insert into emp
values
    ( 7782, 'clark', 'manager', 7839, '1981-06-09', 2450, null, 10 );
insert into emp
values
    ( 7788, 'scott', 'analyst', 7566, '1987-07-13', 3000, null, 20 );
insert into emp
values
    ( 7839, 'king', 'president', null, '1981-11-17', 5000, null, 10 );
insert into emp
values
    ( 7844, 'turner', 'salesman', 7698, '1981-09-08', 1500, 0, 30 );
insert into emp
values
    ( 7876, 'adams', 'clerk', 7788, '1987-07-13', 1100, null, 20 );
insert into emp
values
    ( 7900, 'james', 'clerk', 7698, '1981-12-03', 950, null, 30 );
insert into emp
values
    ( 7902, 'ford', 'analyst', 7566, '1981-12-03', 3000, null, 20 );
insert into emp
values
    ( 7934, 'miller', 'clerk', 7782, '1982-01-23', 1300, null, 10 );

2、根據emp和dept表完成下列作業:

-- 1.列出至少有三個員工的所有部門和部門信息。

SELECT dept.* from dept WHERE dept.DEPTNO IN 
        (SELECT DEPTNO from emp GROUP BY emp.DEPTNO HAVING COUNT(emp.DEPTNO)>=3);

 

-- 2.列出受雇日期早於直接上級的所有員工的編號,姓名,部門名稱

SELECT e1.EMPNO, e1.ENAME,d.DNAME FROM emp e1,dept d
    WHERE e1.HIREDATE < (SELECT e2.HIREDATE FROM emp e2 WHERE e2.empno=e1.MGR)
    AND d.DEPTNO=e1.DEPTNO;

 

-- 3.列出職位為“CLERK”的姓名和部門名稱,部門人數:

SELECT emp_name,dept_name,emp_num FROM (
    SELECT emp.ENAME emp_name,
            dept.DNAME dept_name,
            (SELECT COUNT(emp.EMPNO) FROM emp WHERE emp.DEPTNO=dept.DEPTNO) emp_num 
    FROM emp,dept 
    WHERE emp.JOB='CLERK' AND emp.DEPTNO=dept.DEPTNO
) as t

 

 

*******請大家尊重原創,如要轉載,請注明出處:轉載自:https://www.cnblogs.com/shouhu/,謝謝!!******* 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM