[原创]sql中的子查询详解_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3064 | 回复: 0   主题: [原创]sql中的子查询详解        下一篇 
鲲鹏展翅
注册用户
等级:少校
经验:1148
发帖:79
精华:9
注册:2012-11-19
状态:离线
发送短消息息给鲲鹏展翅 加好友    发送短消息息给鲲鹏展翅 发消息
发表于: IP:您无权察看 2012-11-22 8:48:34 | [全部帖] [楼主帖] 楼主

/*
1.子查询的主要优势为:
·   子查询允许结构化的查询,这样就可以把一个语句的每个部分隔离开。
·   有些操作需要复杂的联合和关联。子查询提供了其它的方法来执行这些操作。
·   在许多人看来,子查询是可读的。实际上,子查询给予人们调用早期SQL“结构化查询语言”的原本的想法,这是子查询的创新。
2.子查询的限定条件:
    1.有一个限定是,一个子查询的外部语句必须是以下语句之一:SELECT, INSERT, UPDATE, DELETE, SET或DO。
    2.还有一个限定是,目前,您不能在一个子查询中修改一个表,又在同一个表中选择。这适用于DELETE, INSERT, REPLACE和UPDATE语句
3.子查询的小结:
    1.子查询作为标量操作数
    2.比较子查询:
      =  >  <  >=  <=  <>
    3.使用ANY, IN和SOME进行子查询
    4.使用ALL进行子查询
    5.行子查询:
      通常用于与对能返回两个或两个以上列的子查询进行比较,如:查询两张表中完全相同的记录
    6.含有EXISTS和NOT EXISTS的子查询
*/
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL);
CREATE TABLE t2 (s1 INT, s2 CHAR(5) NOT NULL);
INSERT INTO t1 VALUES(1, 'fff'),(2,'lll');
INSERT INTO t2 VALUES(1, 'fff'),(2,'lll');
/*1.子查询作为标量操作数:
 在有些情况下,标量子查询不能使用。如果一个语句只允许一个文字值,您不能使用子查询。
 例如,LIMIT要求文字整数自变量,LOAD DATA要求一个文字字符串文件名。您不能使用子查询来提供这些值。
*/
SELECT (SELECT s1 FROM t2) FROM t1;
/*一个标量子查询可以为一个表达式的一部分。不要忘记圆括号。即使是子查询是一个为函数提供自变量的操作数时,也不要忘记圆括号。举例说明:*/
SELECT UPPER((SELECT s1 FROM t2)) FROM t1;
/*2:比较子查询:
 比较子查询中的运算符:=  >  <  >=  <=  <>
 有时,子查询的合法位置只能在比较式的右侧,为了正确性我们尽量把子查询放在比较运算符的右侧
*/
/*使用比较子查询和相关子查询查询出重的记录的id*/
SELECT DISTINCT (s1)
FROM t1
WHERE 1 < (
SELECT COUNT(s1) FROM t1 t WHERE t.s1 = t1.s1
);
/*3.使用ANY, IN和SOME进行子查询
 in 是 =any的别名,二者的意思一样
 not in 不是 <>any的别名,而是<>all的别名
 some是any的别名
*/
SELECT s1,s2
FROM t1
WHERE t1.s1 = ANY (
SELECT s1 FROM t2
);
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 IN    (SELECT s1 FROM t2);
/*使用词语SOME的机会很少,但是本例显示了为什么SOME是有用的。对于多数人来说,
英语短语“a is not equal to any b”的意思是“没有一个b与a相等”,但是在SQL语法中不是这个意思。
该语法的意思是“有部分b与a不相等”。使用<> SOME有助于确认每个人都理解该查询的真正含义。
*/
SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 <> ANY  (SELECT s1 FROM t2);
/*4.使用ALL进行子查询
 词语ALL必须接在一个比较操作符的后面
*/
/*用一条SQL语句 查询出每门课都大于80分的学生姓名*/
CREATE TABLE score(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),SUBJECT VARCHAR(20),score INT);
INSERT INTO score VALUES
(NULL,'张三','语文',81),
(NULL,'张三','数学',75),
(NULL,'李四','语文',76),
(NULL,'李四','数学',90),
(NULL,'王五','语文',81),
(NULL,'王五','数学',100),
(NULL,'王五 ','英语',90);
SELECT DISTINCT ss.name
FROM score ss
WHERE 80 < ALL(
SELECT s.score FROM score s WHERE s.NAME = ss.name
);
SELECT DISTINCT ss.name
FROM score ss
WHERE ss.NAME NOT IN (
SELECT DISTINCT s.name FROM score s WHERE s.score < 80
);
SELECT DISTINCT ss.name
FROM score ss
WHERE ss.NAME <> ALL (
SELECT DISTINCT s.name FROM score s WHERE s.score < 80
);
/*5:行子查询
 行子查询是一个能返回一个单一行的子查询变量,因此可以返回一个以上的列值。
 以下是两个例子:
 SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2);
 SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
 如果在表t2的一个行中,column1=1并且column2=2,则查询结果均为TRUE。

 表达式(1,2)和ROW(1,2)有时被称为行构造符。两者是等同的,在其它的语境中,也是合法的。例如,以下两个语句在语义上
 是等同的(但是目前只有第二个语句可以被优化):
   SELECT * FROM t1 WHERE (column1,column2) = (1,1);
   SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
 行构造符通常用于与对能返回两个或两个以上列的子查询进行比较。例如,以下查询可以答复请求,“在表t1中查找同时也存在于表t2中的所有的行”:
 SELECT column1,column2,column3
 FROM t1
 WHERE (column1,column2,column3) IN
 (SELECT column1,column2,column3 FROM t2);
*/
SELECT s1,s2
FROM t1
WHERE (s1,s2) IN (
SELECT s1,s2 FROM t2
);
SELECT s1,s2
FROM t1
WHERE ROW(s1,s2) = ANY(
SELECT s1,s2 FROM t2
);
/*6.EXISTS和NOT EXISTS
   哪些种类的商店出现在一个或多个城市里?

·                SELECT DISTINCT store_type FROM stores
·                  WHERE EXISTS (SELECT * FROM cities_stores
·                                WHERE cities_stores.store_type = stores.store_type);
·         哪些种类的商店没有出现在任何城市里?

·                SELECT DISTINCT store_type FROM stores
·                  WHERE NOT EXISTS (SELECT * FROM cities_stores
·                                    WHERE cities_stores.store_type = stores.store_type);
·         哪些种类的商店出现在所有城市里?

·                SELECT DISTINCT store_type FROM stores s1
·                  WHERE NOT EXISTS (
·                    SELECT * FROM cities WHERE NOT EXISTS (
·                      SELECT * FROM cities_stores
·                       WHERE cities_stores.city = cities.city
·                       AND cities_stores.store_type = stores.store_type));
*/
CREATE TABLE stores(
store_type INT(10) PRIMARY KEY,
NAME VARCHAR(32)
);
INSERT INTO stores(store_type,NAME) VALUES(1,'汰渍洗衣粉'),(2,'双汇火腿肠'),
(3,'格力空调'),(4,'苹果手机'),
(5,'小米手机'),(6,'三星手机');
CREATE TABLE cities_stores(
city_id INT(10),
store_type INT(10),
CONSTRAINT s_id FOREIGN KEY (store_type) REFERENCES stores(store_type)
);
CREATE TABLE cities(
id INT(4)
);
INSERT INTO cities_stores(city_id,store_type) VALUES(1,1),(1,2),(1,3),
(1,4),(1,5),(1,6),
(2,1),(2,2),(3,6);
/*哪些种类的商店出现在一个或多个城市里?*/
SELECT store_type
FROM stores
WHERE EXISTS (
SELECT city_id FROM cities_stores WHERE cities_stores.store_type = stores.store_type
);
/*哪些种类的商店没有出现在任何城市里?*/
SELECT store_type
FROM stores
WHERE NOT EXISTS (
SELECT city_id FROM cities_stores WHERE cities_stores.store_type = stores.store_type
);
/*哪些种类的商店出现在所有城市里?*/
SELECT store_type
FROM stores
WHERE NOT EXISTS (
SELECT store_type
FROM stores
WHERE NOT EXISTS (
SELECT city_id FROM cities_stores WHERE cities_stores.store_type = stores.store_type
)
);




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论