九州体育网 - 十年信誉网站

多表查问

Reads: 350985 Edit

SELECT查问岂但可以从一张表查问数据,还可以从多张表同时查问数据。查问多张表的语法是:SELECT * FROM <表1> <表2>

例如,同时从students表和classes表的“乘积”,即查问数据,可以这么写:

-- FROM students, classes:
----
SELECT * FROM students, classes;

这种一次查问两个表的数据,查问的结果也是一个二维表,它是students表和classes表的“乘积”,即students表的每一行与classes表的每一行都两两拼在一起返回。结果集的列数是students表和classes表的列数之和,行数是students表和classes表的行数之积。

这种多表查问又称笛卡尔查问,使用笛卡尔查问时要非常小心,由于结果集是目标表的行数乘积,对两个各自有100行记录的表进行笛卡尔查问将返回1万条记录,对两个各自有1万行记录的表进行笛卡尔查问将返回1亿条记录。

你可能还注意到了,上述查问的结果集有两列id和两列name,两列id是因为其中一列是students表的id,而另一列是classes表的id,但是在结果集中,不好区分。两列name同理

要解决这个问题,我们仍然可以利用投影查问的“设置列的别号”来给两个表各自的idname列起别号:

-- set alias:
----
SELECT
    students.id sid,
    students.name,
    students.gender,
    students.score,
    classes.id cid,
    classes.name cname
FROM students, classes;

注意,多表查问时,要使用表名.列名这样的方式来引用列和设置别号,这样就防止了结果集的列名重复问题。但是,用表名.列名这种方式列举两个表的所有列实在是很麻烦,所以SQL还允许给表设置一个别号,让我们在投影查问中引用起来稍微简洁一点:

-- set table alias:
----
SELECT
    s.id sid,
    s.name,
    s.gender,
    s.score,
    c.id cid,
    c.name cname
FROM students s, classes c;

注意到FROM子句给表设置别号的语法是FROM <表名1> <别号1>, <表名2> <别号2>。这样我们用别号sc分别表示students表和classes表。

多表查问也是可以添加WHERE条件的,我们来试试:

-- set where clause:
----
SELECT
    s.id sid,
    s.name,
    s.gender,
    s.score,
    c.id cid,
    c.name cname
FROM students s, classes c
WHERE s.gender = 'M' AND c.id = 1;

这个查问的结果集每行记录都满足条件s.gender = 'M'c.id = 1。添加WHERE条件后结果集的数量大大减少了。

小结

使用多表查问可以获取M x N行记录;

多表查问的结果集可能非常巨大,要小心使用。


Comments

Make a comment