User-Defined Variables

 1 mysql> SET @w := SELECT COUNT(*) FROM course WHERE cteacher='程军';
 2 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version
 3  the right syntax to use near 'SELECT COUNT(*) FROM course WHERE cteacher='程军'' at line 1
 4 mysql> SELECT @w;
 5 +------+
 6 | @w   |
 7 +------+
 8 | NULL |
 9 +------+
10 1 row in set (0.00 sec)
11 
12 mysql> SET @w := (SELECT COUNT(*) FROM course WHERE cteacher='程军');
13 Query OK, 0 rows affected (0.00 sec)
14 
15 mysql> SELECT @w;
16 +------+
17 | @w   |
18 +------+
19 |    2 |
20 +------+
21 1 row in set (0.00 sec)
22 
23 mysql>

 

 1 SHOW TABLES;
 2 DROP TABLE IF EXISTS student;
 3 SHOW TABLES;
 4 CREATE TABLE IF NOT EXISTS student
 5 (
 6     sno int primary key,
 7     sname VARCHAR(20) CHARACTER SET gbk,
 8     sage TINYINT,
 9     shair ENUM('','') CHARACTER SET gbk
10 );
11 INSERT INTO student VALUES('1','李强',23,'');  
12 INSERT INTO student VALUES('2','刘丽',22,'');  
13 INSERT INTO student VALUES('5','张友',22,''); 
14 SELECT * FROM student;
15 
16 SHOW TABLES;
17 DROP TABLE IF EXISTS course;
18 SHOW TABLES;
19 CREATE TABLE IF NOT EXISTS course
20 (
21     cno VARCHAR(10) primary key,
22     cname VARCHAR(20) CHARACTER SET gbk,
23     cteacher  VARCHAR(20) CHARACTER SET gbk
24 );
25 INSERT INTO course VALUES('k1','c语言','王华');  
26 INSERT INTO course VALUES('k5','数据库原理','程军');  
27 INSERT INTO course VALUES('k8','编译原理','程军'); 
28 SELECT * FROM course;
29 
30 SHOW TABLES;
31 DROP TABLE IF EXISTS sc;
32 SHOW TABLES;
33 CREATE TABLE IF NOT EXISTS sc
34 (
35     fk_sno INT NOT NULL,
36     fk_cno VARCHAR(10) NOT NULL,
37     score INT NOT NULL,
38     PRIMARY KEY(fk_sno,fk_cno),
39     FOREIGN KEY(fk_sno) REFERENCES student(sno),
40     FOREIGN KEY(fk_cno) REFERENCES course(cno)
41 );
42 INSERT INTO sc VALUES('1','K1',83);  
43 INSERT INTO sc VALUES('2','K1',85);  
44 INSERT INTO sc VALUES('5','K1',92);  
45 INSERT INTO sc VALUES('2','K5',90);  
46 INSERT INTO sc VALUES('5','K5',84);  
47 INSERT INTO sc VALUES('5','K8',80);  
48 SELECT * FROM sc;

1-检索至少选修"程军"老师所授全部课程的学生姓名(SNAME)
检索选修了“程军”老师所授全部课程的学生姓名

0-检索选修了“程军”老师所授课程的学生

1 SELECT * FROM sc RIGHT JOIN course ON  sc.fk_cno=course.cno;
2 SELECT * FROM (SELECT * FROM sc RIGHT JOIN course ON  sc.fk_cno=course.cno) w RIGHT JOIN student ON w.fk_sno=student.sno;
3 SELECT * FROM (SELECT * FROM sc RIGHT JOIN course ON  sc.fk_cno=course.cno) w RIGHT JOIN student ON w.fk_sno=student.sno WHERE cteacher='程军';

 

集合子集,逐步精确,缩小范围 1-是学生-2-选程老师的课-3-选了程老师所有的课

 /*

假定

“ 某学生选程老师的课程门数等于程老师所开门数”等价于“该学生至少选了程老师的所有的课程”。

*/

 1             SELECT sname FROM student
 2             WHERE
 3             (
 4                 SELECT COUNT(*) FROM 
 5                 (
 6                     SELECT  * FROM (SELECT * FROM sc RIGHT JOIN course ON  sc.fk_cno=course.cno) w RIGHT JOIN student ON w.fk_sno=student.sno 
 7                     WHERE cteacher = '程军' 
 8                 ) wb 
 9                 WHERE wb.sname = student.sname
10             )
11             = 
12             (SELECT COUNT(*) FROM course WHERE cteacher='程军');

 

/* 0-澄清问题:找出至少选了程老师全部课程的学生:学生-没有选程老师的课+学生选了程老师的部分的课+学生选了程老师全部的课    

等价转化:找出选了程老师部分的课或者没有选程老师的课的学生    

数据关系:学生和老师没有数据关系,是两个完全独立的数据对象,分数是桥梁    

等价转化:

  选了部分程老师的课 ,NOT EXISTS (SELECT * FROM sc WHERE sc.sno = student AND sc.cno=course.cno)->FALSE (内层SELECT不空,TRUE,退出)       

  没有选程老师的课 teacher='程军'->FALSE ,后边的不用看了(中层SELECT空,FALSE,退出)       

  外中内-三层SELECT,外层返回的是最终的结果       

  最外层选得的最终量result,学生姓名,它的措施是将各个学生名称带入,逐个检测

1-程序表达: */

 1 SELECT sname FROM student  
 2 WHERE NOT EXISTS  
 3 (  
 4    SELECT * FROM course  
 5    WHERE cteacher='程军' AND NOT EXISTS  
 6    (  
 7        SELECT * FROM sc  
 8        WHERE sc.fk_sno = student.sno AND sc.fk_cno = course.cno
 9     )  
10 ) ;

 

2- 检索选修全部课程的学生姓名(SNAME)。

 1 SELECT sname FROM student
 2 WHERE
 3 (
 4     SELECT COUNT(*) FROM 
 5     (
 6         SELECT  * FROM (SELECT * FROM sc RIGHT JOIN course ON  sc.fk_cno=course.cno) w RIGHT JOIN student ON w.fk_sno=student.sno 
 7     ) wb 
 8     WHERE wb.sname = student.sname
 9 )
10 = 
11 (SELECT COUNT(*) FROM course );
12 
13 SELECT sname FROM student
14 WHERE NOT EXISTS
15 (
16     SELECT * FROM course
17     WHERE NOT EXISTS 
18     (
19         SELECT * FROM sc
20         WHERE sc.fk_sno = student.sno AND sc.fk_cno = course.cno
21     )
22 );
23 
24 SELECT * FROM course
25 WHERE NOT EXISTS 
26 (
27     SELECT 3>5
28 );
29 
30 SELECT * FROM course
31 WHERE  EXISTS 
32 (
33     SELECT 3>5
34 );

explain

 1 mysql> explain
 2     -> SELECT sname FROM student
 3     -> WHERE
 4     -> (
 5     ->  SELECT COUNT(*) FROM
 6     ->  (
 7     ->          SELECT  * FROM (SELECT * FROM sc RIGHT JOIN course ON  sc.fk_cno=course.cno) w RIGHT JOIN student ON w.fk_sno=student.sno
 8     ->  ) wb
 9     ->  WHERE wb.sname = student.sname
10     -> )
11     -> =
12     -> (SELECT COUNT(*) FROM course );
13 +----+--------------------+---------+------------+--------+----------------+---------+---------+-------------------+------+----------+------------------------------+
14 | id | select_type        | table   | partitions | type   | possible_keys  | key     | key_len | ref               | rows | filtered | Extra                        |
15 +----+--------------------+---------+------------+--------+----------------+---------+---------+-------------------+------+----------+------------------------------+
16 |  1 | PRIMARY            | student | NULL       | ALL    | NULL           | NULL    | NULL    | NULL              |    3 |   100.00 | Using where                  |
17 |  5 | SUBQUERY           | NULL    | NULL       | NULL   | NULL           | NULL    | NULL    | NULL              | NULL |     NULL | Select tables optimized away |
18 |  2 | DEPENDENT SUBQUERY | student | NULL       | ALL    | NULL           | NULL    | NULL    | NULL              |    3 |    33.33 | Using where                  |
19 |  2 | DEPENDENT SUBQUERY | sc      | NULL       | ref    | PRIMARY,fk_cno | PRIMARY | 4       | w0811.student.sno |    2 |   100.00 | Using index                  |
20 |  2 | DEPENDENT SUBQUERY | course  | NULL       | eq_ref | PRIMARY        | PRIMARY | 12      | w0811.sc.fk_cno   |    1 |   100.00 | Using index                  |
21 +----+--------------------+---------+------------+--------+----------------+---------+---------+-------------------+------+----------+------------------------------+
22 5 rows in set, 2 warnings (0.00 sec)
23 
24 mysql>
25 mysql> explain
26     -> SELECT sname FROM student
27     -> WHERE NOT EXISTS
28     -> (
29     ->  SELECT * FROM course
30     ->  WHERE NOT EXISTS
31     ->  (
32     ->          SELECT * FROM sc
33     ->          WHERE sc.fk_sno = student.sno AND sc.fk_cno = course.cno
34     ->  )
35     -> );
36 +----+--------------------+---------+------------+--------+----------------+---------+---------+------------------------------------+------+----------+--------------------------+
37 | id | select_type        | table   | partitions | type   | possible_keys  | key     | key_len | ref                                | rows | filtered | Extra                    |
38 +----+--------------------+---------+------------+--------+----------------+---------+---------+------------------------------------+------+----------+--------------------------+
39 |  1 | PRIMARY            | student | NULL       | ALL    | NULL           | NULL    | NULL    | NULL                               |    3 |   100.00 | Using where              |
40 |  2 | DEPENDENT SUBQUERY | course  | NULL       | index  | NULL           | PRIMARY | 12      | NULL                               |    3 |   100.00 | Using where; Using index |
41 |  3 | DEPENDENT SUBQUERY | sc      | NULL       | eq_ref | PRIMARY,fk_cno | PRIMARY | 16      | w0811.student.sno,w0811.course.cno |    1 |   100.00 | Using index              |
42 +----+--------------------+---------+------------+--------+----------------+---------+---------+------------------------------------+------+----------+--------------------------+
43 3 rows in set, 3 warnings (0.00 sec)
44 
45 mysql>

 “带入遍历”,“重复循环”,这是上边代码原貌,而两种思路的区别仅仅是让计算机计算时怎样“重复次数”少一点。

 

http://blog.csdn.net/wolfofsiberian/article/details/39346781

发问:

0-语言只是工具而已,不是解决问题方法的源泉,怎么减少对接语法API的时间?

 

posted @ 2016-08-13 19:12  papering  阅读(578)  评论(4编辑  收藏  举报