十一级信息学实践(CBSE)/连接与子查询
外观
SQL 最重要的方面是其关系特性。您可以查询、比较和计算两个具有完全不同结构的不同表。连接和子选择是连接表的两种方法。两种连接表的方法应该给出相同的结果。在大多数 SQL 平台上,自然连接更快。
在下面的例子中,一个学生试图学习印地语中数字的叫法。
CREATE TABLE english (Tag int, Inenglish varchar(255)); CREATE TABLE hindi (Tag int, Inhindi varchar(255));
INSERT INTO english (Tag, Inenglish) VALUES (1, 'One'); INSERT INTO english (Tag, Inenglish) VALUES (2, 'Two'); INSERT INTO english (Tag, Inenglish) VALUES (3, 'Three');
INSERT INTO hindi (Tag, Inhindi) VALUES (2, 'Do'); INSERT INTO hindi (Tag, Inhindi) VALUES (3, 'Teen'); INSERT INTO hindi (Tag, Inhindi) VALUES (4, 'Char');
从英文中选择 * | 从印地语中选择 * | ||
标签 | 英文 | 标签 | 印地语 |
1 | 一 | 2 | 做 |
2 | 二 | 3 | 青少年 |
3 | 三 | 4 | 炭 |
笛卡尔积连接是指将一个表中的每一行与另一个表中的每一行连接起来。
SELECT * FROM english, hindi
它也被称为交叉连接,可以这样写
SELECT * FROM english CROSS JOIN hindi
标签 | 英文 | 标签 | 印地语 |
1 | 一 | 2 | 做 |
2 | 二 | 3 | 青少年 |
3 | 三 | 4 | 炭 |
SELECT hindi.Tag, english.Inenglish, hindi.Inhindi FROM english, hindi WHERE english.Tag = hindi.Tag
标签 | 英文 | 印地语 |
2 | 二 | 做 |
3 | 三 | 青少年 |
您也可以将相同的查询写成
SELECT hindi.Tag, english.Inenglish, hindi.Inhindi FROM english INNER JOIN hindi ON english.Tag = hindi.Tag
使用“using”的自然连接(兼容:MySQL 4+;但在 MySQL 5 中已更改)以下使用“USING”方法的语句将显示相同的结果。
SELECT hindi.tag, hindi.Inhindi, english.Inenglish FROM hindi NATURAL JOIN english USING (Tag)
标签 | 英文 | 标签 | 印地语 |
1 | 一 | ||
2 | 二 | 2 | 做 |
3 | 三 | 3 | 青少年 |
4 | 炭 |
语法如下
SELECT field1, field2 FROM table1 LEFT JOIN table2 ON field1=field2
SELECT e.Inenglish as English, e.Tag, '--no row--' as Hindi FROM english AS e LEFT JOIN hindi AS h ON e.Tag=h.Tag WHERE h.Inhindi IS NULL
English tag Hindi One 1 --no row-
SELECT '--no row--' AS English, h.tag, h.Inhindi AS Hindi FROM english AS e RIGHT JOIN hindi AS h ON e.Tag=h.Tag WHERE e.Inenglish IS NULL
英文标签印地语--无行--4 炭
- 确保您在两个表中具有相同的名称和相同的数据类型。
- 关键字 LEFT 和 RIGHT 不是绝对的,它们仅在给定语句的上下文中起作用:我们可以颠倒表的顺序并颠倒关键字,结果将相同。
- 如果没有指定连接类型为内部或外部,则将执行为内部连接。
对于 v5.1,MySQL 不提供 FULL OUTER JOIN。您可以使用一系列联合的 SELECT 语句来模拟它。
可以连接两个以上的表
SELECT ... FROM a JOIN (b JOIN c on b.id=c.id) ON a.id=b.id
以下来自 *萨凡纳* 的示例
mysql> SELECT group_type.type_id, group_type.name, COUNT(people_job.job_id) AS count FROM group_type JOIN (groups JOIN people_job ON groups.group_id = people_job.group_id) ON group_type.type_id = groups.type GROUP BY type_id ORDER BY type_id +---------+--------------------------------------+-------+ | type_id | name | count | +---------+--------------------------------------+-------+ | 1 | Official GNU software | 148 | | 2 | non-GNU software and documentation | 268 | | 3 | www.gnu.org portion | 4 | | 6 | www.gnu.org translation team | 5 | +---------+--------------------------------------+-------+ 4 rows in set (0.02 sec)
(兼容:Mysql 4.1 及更高版本...*粗体文字*)
- SQL 子查询允许您将一个查询的结果用作另一个查询的一部分。
- 子查询通常是编写语句的自然方式。
- 允许您将查询分解成片段并组装起来。
- 允许某些其他方式无法构建的查询。不使用子查询,您必须分两步完成。
- 子查询始终出现在 WHERE(或 HAVING)子句中。
- 子查询 SELECT 中只能有一个字段。这意味着子查询只能生成一列数据作为其结果。
- 不允许使用 ORDER BY;这没有意义。
- 通常引用子查询中主表列的名称。
- 这定义了正在运行子查询的主表的当前行。这被称为外部引用。
例如,如果 RepOffice=Offices 表中的 OfficeNbr,列出销售配额超过单个销售人员配额总和的办公室
SELECT City FROM Offices WHERE Target > ???
??? 是销售人员配额的总和,即
SELECT SUM(Quota) FROM SalesReps WHERE RepOffice = OfficeNbr
我们将这些结合起来得到
SELECT City FROM Offices WHERE Target > (SELECT SUM(Quota) FROM SalesReps WHERE RepOffice = OfficeNbr)
显示所有有订单或信用额度 > 50,000 美元的客户。使用 DISTINCT 词语仅列出客户一次。
SELECT DISTINCT CustNbr FROM Customers, Orders WHERE CustNbr = Cust AND (CreditLimit>50000 OR Amt>50000);