1.元组变量
SELECT * FROM a AS x, a AS y;
结果是显示自己和自己的笛卡尔乘积。
如果查询中对于某一个关系使用了多次,为了区别他们的属性,需要对关系定义别名,然后用 别名.属性 来区分。
SELECT Star1.name, Star2.name FROM MovieStar Star1, MovieStar Star2 WHERE Star1.address = Star2.address AND Star1.name < Star2.name;
注意,最后名称要用<, 如果只用 <> 会导致同样的两个名字输出两遍(仅顺序不同)
2.消除属性歧义
如果几个关系都有相同的属性名,通过 关系名.属性名 解决。
SELECT MovieStar.name, MovieExec.name FROM MovieStar, MovieExec WHERE MovieStar.address = MovieExec.address;
3.
Mysql 中不支持 SQL 的 INTERSECT(交集), EXCEPT(差),UNION(并集)关键字
4.子查询
某个查询是另一个查询的一部分时,称为子查询。
4.1 产生标量值的子查询(子查询的结果仅有一个唯一值)
SELECT name FROM MovieExec WHERE cert# = (SELECT producerC# FROM Movies WHERE title = 'Star Wars');
上面语句成功的必要条件:子查询中返回的producerC#只能有一个成员!多了会报错!!
如图,是一个返回了多个值的例子。报错Subquery returns more than 1 row.
4.2关系的条件表达式
下面的表达式,必须在关系是子查询的时候使用,返回布尔值结果。
EXISTS R: R非空为真
s IN R: s等于R中的某个值
s NOT IN R: s不等于R中任何一个值
s > ALL R: s比一元R中的任意值都大(R未必一元,只要s与R的分量相同即可)
s > ANY R: s至少大于一元R中的某一个值
NOT 可以加在前面表示取反: NOT EXISTS R; NOT s > ANY R;
上述例子中的 > 可以换成 =, <>, <, >=, <= 中的任何一个。
SELECT name FROM MovieExec WHERE cert# IN (SELECT producerC# FROM Movies WHERE (title, year) IN (SELECT movieTitle, movieYear FROM StarsIn WHERE starName = 'Harrison Ford' ) );
4.3 关联子查询
SELECT title FROM Movies Old WHERE year < ANY (SELECT year FROM Movies WHERE title = Old.title );
找到被多部电影同时使用的电影名,一个电影名出现n次则输出n-1次。
与上面的不同在于:Old.title的值不是固定的
4.4 FROM子句中的子查询
SELECT name FROM MovieExec, (SELECT producerC# FROM Movies, StarsIn WHERE title = movieTitle AND year = movieYear AND starName = 'Harrison Ford' )Prod WHERE cert# = Prod.producerC#;
4.5连接表达式-交叉连接
SELECT * FROM Movies CROSS JOIN StarsIn;
CROSS JOIN: 表示交叉连接,即积或笛卡尔积。
4.6连接表达式-θ连接
θ连接: 在笛卡尔积的基础上做条件选择。
JOIN ... ON: ON后面跟条件
Movies JOIN StarsIn ON title = movieTitle AND year = movieYear;
SELECT title, year, length, genre FROM Movies JOIN StarsIn ON title = movieTitle AND year = movieYear;
4.7连接表达式-自然连接
自然连接:把两个关系中相同属性的值相同的取出。如
相同的属性不会多次出现,这是自然连接和笛卡尔积的关键区别
NATURAL JOIN:
SELECT * FROM Nums1 NATURAL JOIN Nums2;
4.8连接表达式-外连接
外连接:把自然连接中的的悬浮元祖考虑进来,把没有值的地方用空显示。
关系U | 关系V | 左外连接结果 | 右外连接结果 | 全外连接结果 |
左外连接:MovieStar NATURAL LEFT OUTER JOIN MovieExec;
右外连接:MovieStar NATURAL RIGHT OUTER JOIN MovieExec;
全外连接:MovieStar NATURAL FULL OUTER JOIN MovieExec; (mysql不支持全外连接,但是左右外连接支持)
书上说,外连接也可以加条件,方法是把NATURAL去掉后在JOIN后面通过ON关键字加条件。但是我在mysql上实验了下,发现不行。去掉NATURAL后得到的结果就不是自然连接了,相同的属性名会出现多次,跟笛卡尔积比较像。