sql连接查询与子查询
A. 关于sql子查询和连接查询的问题
子查询 当一个查询是另一个查询的条件时,称之为子查询
通过连接运算符可以实现多个表查询是连接查询
B. SQL server数据库中的多表连接查询和子查询的区别
连接查询是
通过主外键
让多个表数据对应
成一个表数据,而子查询是查到的数据
利用这个数据再查别的
如查张三的年级ID
再用这个年级ID去查对应的年级名
C. sql子查询和连接查询的区别是什么呢悬赏100求答案
子查询就是查询中又嵌套的查询,嵌套的级数随各数据库厂商的设定而有所不同,一般最大嵌套数不超过15级,实际应用中,一般不要超过2级,否则代码难以理解.一般来说,所有嵌套子查询都可改写为非嵌套的查询,但是这样将导致代码量增大.子查询就如递归函数一样,有时侯使用起来能达到事半功倍之效,只是其执行效率同样较低,有时用自身连接可代替某些子查询,另外,某些相关子查询也可改写成非相关子查询
表连接都可以用子查询,但不是所有子查询都能用表连接替换,子查询比较灵活,方便,形式多样,适合用于作为查询的筛选条件,而表连接更适合与查看多表的数据
子查询不一定需要两个表有关联字段,而连接查询必须有字段关联(所谓的主外键关系)
D. SQL查询语句
一、简单查询语句
1. 查看表结构
SQL>DESC emp;
2. 查询所有列
SQL>SELECT * FROM emp;
3. 查询指定列
SQL>SELECT empmo, ename, mgr FROM emp;
SQL>SELECT DISTINCT mgr FROM emp; 只显示结果不同的项
4. 查询指定行
SQL>SELECT * FROM emp WHERE job='CLERK';
5. 使用算术表达式
SQL>SELECT ename, sal*13+nvl(comm,0) FROM emp;
nvl(comm,1)的意思是,如果comm中有值,则nvl(comm,1)=comm; comm中无值,则nvl(comm,1)=0。
SQL>SELECT ename, sal*13+nvl(comm,0) year_sal FROM emp; (year_sal为别名,可按别名排序)
SQL>SELECT * FROM emp WHERE hiredate>'01-1月-82';
6. 使用like操作符(%,_)
%表示一个或多个字符,_表示一个字符,[charlist]表示字符列中的任何单一字符,[^charlist]或者[!charlist]不在字符列中的任何单一字符。
SQL>SELECT * FROM emp WHERE ename like 'S__T%';
7. 在where条件中使用In
SQL>SELECT * FROM emp WHERE job IN ('CLERK','ANALYST');
8. 查询字段内容为空/非空的语句
SQL>SELECT * FROM emp WHERE mgr IS/IS NOT NULL;
9. 使用逻辑操作符号
SQL>SELECT * FROM emp WHERE (sal>500 or job='MANAGE') and ename like 'J%';
10. 将查询结果按字段的值进行排序
SQL>SELECT * FROM emp ORDER BY deptno, sal DESC; (按部门升序,并按薪酬降序)
二、复杂查询
1. 数据分组(max,min,avg,sum,count)
SQL>SELECT MAX(sal),MIN(age),AVG(sal),SUM(sal) from emp;
SQL>SELECT * FROM emp where sal=(SELECT MAX(sal) from emp));
SQL>SELEC COUNT(*) FROM emp;
2. group by(用于对查询结果的分组统计) 和 having子句(用于限制分组显示结果)
SQL>SELECT deptno,MAX(sal),AVG(sal) FROM emp GROUP BY deptno;
SQL>SELECT deptno, job, AVG(sal),MIN(sal) FROM emp group by deptno,job having AVG(sal)<2000;
对于数据分组的总结:
a. 分组函数只能出现在选择列表、having、order by子句中(不能出现在where中)
b. 如果select语句中同时包含有group by, having, order by,那么它们的顺序是group by, having, order by。
c. 在选择列中如果有列、表达式和分组函数,那么这些列和表达式必须出现在group by子句中,否则就是会出错。
使用group by不是使用having的前提条件。
3. 多表查询
SQL>SELECT e.name,e.sal,d.dname FROM emp e, dept d WHERE e.deptno=d.deptno order by d.deptno;
SQL>SELECT e.ename,e.sal,s.grade FROM emp e,salgrade s WHER e.sal BETWEEN s.losal AND s.hisal;
4. 自连接(指同一张表的连接查询)
SQL>SELECT er.ename, ee.ename mgr_name from emp er, emp ee where er.mgr=ee.empno;
5. 子查询(嵌入到其他sql语句中的select语句,也叫嵌套查询)
5.1 单行子查询
SQL>SELECT ename FROM emp WHERE deptno=(SELECT deptno FROM emp where ename='SMITH');查询表中与smith同部门的人员名字。因为返回结果只有一行,所以用“=”连接子查询语句
5.2 多行子查询
SQL>SELECT ename,job,sal,deptno from emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno=10);查询表中与部门号为10的工作相同的员工的姓名、工作、薪水、部门号。因为返回结果有多行,所以用“IN”连接子查询语句。
in与exists的区别: exists() 后面的子查询被称做相关子查询,它是不返回列表的值的。只是返回一个ture或false的结果,其运行方式是先运行主查询一次,再去子查询里查询与其对 应的`结果。如果是ture则输出,反之则不输出。再根据主查询中的每一行去子查询里去查询。in()后面的子查询,是返回结果集的,换句话说执行次序和 exists()不一样。子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去。符合要求的输出,反之则不输出。
5.3 使用ALL
SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ALL (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MAX(sal) FROM emp WHERE deptno=30);查询工资比部门号为30号的所有员工工资都高的员工的姓名、薪水和部门号。以上两个语句在功能上是一样的,但执行效率上,函数会高 得多。
5.4 使用ANY
SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ANY (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MIN(sal) FROM emp WHERE deptno=30);查询工资比部门号为30号的任意一个员工工资高(只要比某一员工工资高即可)的员工的姓名、薪水和部门号。以上两个语句在功能上是 一样的,但执行效率上,函数会高得多。
5.5 多列子查询
SQL>SELECT * FROM emp WHERE (job, deptno)=(SELECT job, deptno FROM emp WHERE ename='SMITH');
5.6 在from子句中使用子查询
SQL>SELECT emp.deptno,emp.ename,emp.sal,t_avgsal.avgsal FROM emp,(SELECT emp.deptno,avg(emp.sal) avgsal FROM emp GROUP BY emp.deptno) t_avgsal where emp.deptno=t_avgsal.deptno AND emp.sal>t_avgsal.avgsal ORDER BY emp.deptno;
5.7 分页查询
数据库的每行数据都有一个对应的行号,称为rownum.
SQL>SELECT a2.* FROM (SELECT a1.*, ROWNUM rn FROM (SELECT * FROM emp ORDER BY sal) a1 WHERE ROWNUM<=10) a2 WHERE rn>=6;
指定查询列、查询结果排序等,都只需要修改最里层的子查询即可。
5.8 用查询结果创建新表
SQL>CREATE TABLE mytable (id,name,sal,job,deptno) AS SELECT empno,ename,sal,job,deptno FROM emp;
5.9 合并查询(union 并集, intersect 交集, union all 并集+交集, minus差集)
SQL>SELECT ename, sal, job FROM emp WHERE sal>2500 UNION(INTERSECT/UNION ALL/MINUS) SELECT ename, sal, job FROM emp WHERE job='MANAGER';
合并查询的执行效率远高于and,or等逻辑查询。
5.10 使用子查询插入数据
SQL>CREATE TABLE myEmp(empID number(4), name varchar2(20), sal number(6), job varchar2(10), dept number(2)); 先建一张空表;
SQL>INSERT INTO myEmp(empID, name, sal, job, dept) SELECT empno, ename, sal, job, deptno FROM emp WHERE deptno=10; 再将emp表中部门号为10的数据插入到新表myEmp中,实现数据的批量查询。
5.11 使用了查询更新表中的数据
SQL>UPDATE emp SET(job, sal, comm)=(SELECT job, sal, comm FROM emp where ename='SMITH') WHERE ename='SCOTT';
E. SQL用连接查询好还是子查询好
在
transact-sql
中,包括子查询的语句和不包括子查询但语义上等效的语句在性能方面通常没有区别。但是,在一些必须检查存在性的情况中,使用联接会产生更好的性能。否则,为确保消除重复值,必须为外部查询的每个结果都处理嵌套查询。所以在这些情况下,联接方式会产生更好的效果。
F. SQL Server中子查询好还是连接查询好啊
从效率和性能来看:首选联接查询,如果联接查询实现不了,就用子查询.(也就是说:联接查询能实现的,子查询都能实现,子查询能实现的,联接查询比一定能实现)子查询的效率和性能要比联接查询底一些.
G. sql子查询与表连接查询
比如说有2张表,一个表(useinfo 学员信息),包含字段userid(int),username(varhcar 50). 一个表(useinfo 学员成绩表),包含字段scoreId(int),userid(int),score(varhcar 50).如果要连表查询没参加考试学员的信息。1)用子查询: select userid, username from useinfo where userid not in(select userid from score). 假设useinfo 有4条数据,scroe表有3条数据,说明有1名同学没参加考试。用子查询就能查 出没参加考试人的信息。2)用连表查询 select * from userinfo ,scroe where userinfo.id<> scroe.userinfo 假设useinfo 有4条数据,scroe表有3条数据,说明有1名同学没参加考试。这时用连表查询,查出的结果为9条记录,显然不正确,这时子查询就不能被连表查询替换。因为连表查询结果是总结果4*3-3(匹配的结果)=9.
H. SQL必知必会(二)函数、子查询
#文本处理函数
UPPER() --大写
LOWER() --小写
SOUNDEX() --读音类似
LENGTH() --字符串长度
#日期和时间处理函数
SELECT order_code
FROM order_table
WHERE DATEPART(yy,order_date)=2012
#to_char()函数提取日期成分,MySQL可用year()函数提取年份
SELECT order_num
FROM order_table
WHERE to_number(to_char(order_date,'YYYY'))=2012; --to_char提取日期成分to_number转化为数值
SELECT order_num
FROM order_table
WHERE order_date BETWEEN to_date('01-01-2012') AND to_date('12-31--2012'); --字符串转日期
#数值处理函数
ABS() --绝对值
COS() --余弦
EXP() --指数值
PI() --圆周率
SIN() --正弦
SQRT() --平方根
TAN() --正切
#平均数AVG()
SELECT AVG(a) AS avg_a
FROM tableA
WHERE a='DLL01';
#计数
SELECT COUNT(*) AS num_cust --对所有行计数,不管是否NULL值
FROM tableA;
SELECT COUNT(a) AS num_a --指定了列名,会忽略NULL值
FROM tableA;
#最值
MAX()和MIN(),忽略NULL值
#总值SUM(),忽略NULL值
SELECT SUM(price*quantity) AS total_price
FROM tableA
WHERE order_code=20008
#以上聚集函数只包含不同值
SELECT AVG(DISTINCT order_price) AS avg_price
FROM tableA
WHERE id='DLL01';
两个子句:GROUP BY 和 HAVING
#GROUP BY创建分组HAVING过滤分组
SELECT vend_id, COUNT(*) AS num_prods
FROM tableA
WHERE price>=4
GROUP BY vend_id
HAVING COUNT(*)>=2;
ORDER BY price --GROUP BY在WHERE之后在ORDER BY之前
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
#子查询顺序为从内而外
SELECT order_num
FROM tableA
WHERE id='DLL01';
(输出20007和20008)
SELECT id
FROM tableB
WHERE order_num IN(20007,20008);
#合并为子查询。只能查询单个列
SELECT id
FROM tableB
WHERE order_num IN (SELECT order_num FROM tableA WHERE id='DLL01')
SELECT cust_name,
cust_state
(SELECT COUNT(*)
FROM Orders
WHERE Orders.cust_id=Customers.cust_id) AS orders
FROM Customers
ORDER BY cust_name;
#Orders.cust_id=Customers.cust_id完全限定列名,在两张表中名字相同列拿出来比较,防止歧义
I. SQL连接查询转换为子查询
SELECT
s.id AS "学号",
(select c.name from classes c where c.id = s.class_id) AS "班级",
s.name AS "名字",
s.gender AS "性别",
s.score AS "分数"
FROM students AS s
J. sql 语句中,连接查询与子查询,区分不是很明确
连接查询效率高,但是会导致重复数据。如果确定连接查询不会重复,那么用连接查询会比较好。
子查询效率低,但是可以避免重复数据。如果要到子查询,尽量使用索引提高效率。有些情况必须避免重复数据,那就只能用子查询。
但是具体问题还是要具体分析。如果主表很小,子表很大,并且有索引,是可以使用子查询的,如果主表很大,那就尽量避免子查询了。