MySQL - 自连接
MySQL 自连接
MySQL 自连接 用于将一个表与其自身连接,就像两个表一样。为此,MySQL 语句中至少要临时重命名一个表。
自连接是一种内连接,用于需要比较同一张表的两列;可能是为了建立它们之间的关系。换句话说,当一个表同时包含外键和主键时,它就与自身连接。
但是,与其他连接查询不同,我们使用 WHERE 子句来指定表与自身连接的条件,而不是 ON 子句。
语法
以下是 MySQL 中自连接的基本语法 -
SELECT 列名(s) FROM table1 a, table1 b WHERE a.common_field = b.common_field;
此处,WHERE 子句可以根据您的需求使用任何给定的表达式。
示例
自连接只需要一个表来连接自身;因此,让我们创建一个 CUSTOMERS 表,其中包含客户详细信息,例如他们的姓名、年龄、地址和薪水。
CREATE TABLE CUSTOMERS ( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, ADDRESS CHAR (25), SALARY DECIMAL (18, 2), PRIMARY KEY (ID) );
现在使用 INSERT 语句将值插入到该表中,如下所示 -
INSERT INTO CUSTOMERS VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 ), (2, 'Khilan', 25, 'Delhi', 1500.00 ), (3, 'Kaushik', 23, 'Kota', 2000.00 ), (4, 'Chaitali', 25, 'Mumbai', 6500.00 ), (5, 'Hardik', 27, 'Bhopal', 8500.00 ), (6, 'Komal', 22, 'Hyderabad', 4500.00 ), (7, 'Muffy', 24, 'Indore', 10000.00 );
该表将创建为 −
ID | NAME | AGE | ADDRESS | SALARY |
---|---|---|---|---|
1 | Ramesh | 32 | Ahmedabad | 2000.00 |
2 | Khilan | 25 | Delhi | 1500.00 |
3 | Kaushik | 23 | Kota | 2000.00 |
4 | Chaitali | 25 | Mumbai | 6500.00 |
5 | Hardik | 27 | Bhopal | 8500.00 |
6 | Komal | 22 | Hyderabad | 4500.00 |
7 | Muffy | 24 | Indore | 10000.00 |
现在,让我们使用以下自连接查询来连接此表。我们的目标是根据上述客户的收入建立他们之间的关系。我们借助 WHERE 子句来实现这一点。
SELECT a.ID, b.NAME as EARNS_HIGHER, a.NAME as EARNS_LESS, a.SALARY as LOWER_SALARY FROM CUSTOMERS a, CUSTOMERS b WHERE a.SALARY < b.SALARY;
输出
显示的结果表将列出所有收入低于其他客户的客户 -
ID | EARNS_HIGHER | EARNS_LESS | LOWER_SALARY |
---|---|---|---|
2 | Ramesh | Khilan | 1500.00 |
2 | Kaushik | Khilan | 1500.00 |
6 | Chaitali | Komal | 4500.00 |
3 | Chaitali | Kaushik | 2000.00 |
2 | Chaitali | Khilan | 1500.00 |
1 | Chaitali | Ramesh | 2000.00 |
6 | Hardik | Komal | 4500.00 |
4 | Hardik | Chaitali | 6500.00 |
3 | Hardik | Kaushik | 2000.00 |
2 | Hardik | Khilan | 1500.00 |
1 | Hardik | Ramesh | 2000.00 |
3 | Komal | Kaushik | 2000.00 |
2 | Komal | Khilan | 1500.00 |
1 | Komal | Ramesh | 2000.00 |
6 | Muffy | Komal | 4500.00 |
5 | Muffy | Hardik | 8500.00 |
4 | Muffy | Chaitali | 6500.00 |
3 | Muffy | Kaushik | 2000.00 |
2 | Muffy | Khilan | 1500.00 | 1 | Muffy | Ramesh | 2000.00 |
使用 ORDER BY 子句进行自连接
此外,使用自连接将一个表与其自身连接后,还可以使用 ORDER BY 子句对组合表中的记录进行升序排序。其语法如下:
SELECT 列名 FROM table1 a, table1 b WHERE a.common_field = b.common_field ORDER BY 列名;
示例
在此示例中,执行以下查询将使用 WHERE 子句中的自连接将 CUSTOMERS 表与其自身连接。然后,使用 ORDER BY 子句根据指定列对记录进行升序排列。此处,我们根据工资列对记录进行排序
SELECT a.ID, b.NAME as EARNS_HIGHER, a.NAME as EARNS_LESS, a.SALARY as LOWER_SALARY FROM CUSTOMERS a, CUSTOMERS b WHERE a.SALARY < b.SALARY ORDER BY a.SALARY;
输出
结果表显示如下 -
ID | EARNS_HIGHER | EARNS_LESS | LOWER_SALARY |
---|---|---|---|
2 | Ramesh | Khilan | 1500.00 |
2 | Kaushik | Khilan | 1500.00 |
2 | Chaitali | Khilan | 1500.00 |
2 | Hardik | Khilan | 1500.00 |
2 | Komal | Khilan | 1500.00 |
2 | Muffy | Khilan | 1500.00 |
3 | Chaitali | Kaushik | 2000.00 |
1 | Chaitali | Ramesh | 2000.00 |
3 | Hardik | Kaushik | 2000.00 |
1 | Hardik | Ramesh | 2000.00 |
3 | Komal | Kaushik | 2000.00 |
1 | Komal | Ramesh | 2000.00 |
3 | Muffy | Kaushik | 2000.00 |
1 | Muffy | Ramesh | 2000.00 |
6 | Chaitali | Komal | 4500.00 |
6 | Hardik | Komal | 4500.00 |
6 | Muffy | Komal | 4500.00 |
4 | Hardik | Chaitali | 6500.00 |
4 | Muffy | Chaitali | 6500.00 |
5 | Muffy | Hardik | 8500.00 |
使用客户端程序进行自连接
我们也可以使用客户端程序对一个或多个表执行自连接操作。
语法
要通过 PHP 程序执行自连接,我们需要使用 mysqli 函数 query() 执行 SQL 查询,如下所示 -
$sql = 'SELECT a.tutorial_id, a.tutorial_title, a.tutorial_author, b.tutorial_count FROM tutorials_tbl a, tcount_tbl b WHERE a.tutorial_author = b.tutorial_author'; $mysqli->query($sql);
要通过 JavaScript 程序执行自连接,我们需要使用 mysql2 库的 query() 函数执行 SQL 查询,如下所示 -
sql = "SELECT a.tutorial_id, a.tutorial_title, a.tutorial_author, b.tutorial_count FROM tutorials_tbl a, tcount_tbl b WHERE a.tutorial_author = b.tutorial_author"; con.query(sql);
要通过 Java 程序执行自连接,我们需要使用 JDBC 函数 executeQuery() 执行 SQL 查询,如下所示 -
String sql = "SELECT a.tutorial_id, a.tutorial_title, a.tutorial_author, b.tutorial_count FROM tutorials_tbl a, tcount_tbl b WHERE a.tutorial_author = b.tutorial_author"; statement.executeQuery(sql);
要通过 Python 程序执行自连接,我们需要使用 MySQL Connector/Python 的 execute() 函数执行 SQL 查询,如下所示 -
self_join_query = "SELECT a.ID, b.NAME as EARNS_HIGHER, a.NAME as EARNS_LESS, a.SALARY as LOWER_SALARY FROM CUSTOMERS a, CUSTOMERS b WHERE a.SALARY
示例
以下是程序 -
$dbhost = 'localhost'; $dbuser = 'root'; $dbpass = 'password'; $dbname = 'TUTORIALS'; $mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname); if ($mysqli->connect_errno) { printf("Connect failed: %s
", $mysqli->connect_error); exit(); } // printf('Connected successfully.
'); $sql = 'SELECT a.tutorial_id, a.tutorial_title, a.tutorial_author, b.tutorial_count FROM tutorials_tbl a, tcount_tbl b WHERE a.tutorial_author = b.tutorial_author'; $result = $mysqli->query($sql); if ($result->num_rows > 0) { echo " following is the details after executing SELF join! "; while ($row = $result->fetch_assoc()) { printf("Id: %s, Title: %s, Author: %s, Count: %d", $row["tutorial_id"], $row["tutorial_title"], $row["tutorial_author"], $row["tutorial_count"]); printf(" "); } } else { printf('No record found.
'); } mysqli_free_result($result); $mysqli->close();
输出
获得的输出如下 -
following is the details after executing SELF join! Id: 3, Title: JAVA Tutorial, Author: Sanjay, Count: 1
var mysql = require("mysql2"); var con = mysql.createConnection({ host: "localhost", user: "root", password: "password", }); //连接到 MySQL con.connect(function (err) { if (err) throw err; // console.log("Connected successfully...!"); // console.log("--------------------------"); sql = "USE TUTORIALS"; con.query(sql); //Self Join sql = "SELECT a.tutorial_id, a.tutorial_title, a.tutorial_author, b.tutorial_count FROM tutorials_tbl a, tcount_tbl b WHERE a.tutorial_author = b.tutorial_author"; con.query(sql, function (err, result) { if (err) throw err; console.log(result); }); });
输出
生成的输出如下 -
[ { tutorial_id: 1, tutorial_title: 'Learn PHP', tutorial_author: 'John Poul', tutorial_count: 2 } ]
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class SelfJoin { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/TUTORIALS"; String username = "root"; String password = "password"; try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection connection = DriverManager.getConnection(url, username, password); Statement statement = connection.createStatement(); System.out.println("Connected successfully...!"); //MySQL Self JOIN...!; String sql = "SELECT a.tutorial_id, a.tutorial_title, a.tutorial_author, b.tutorial_count FROM tutorials_tbl a, tcount_tbl b WHERE a.tutorial_author = b.tutorial_author"; ResultSet resultSet = statement.executeQuery(sql); System.out.println("Table records after Self Join...!"); while (resultSet.next()){ System.out.println(resultSet.getString(1)+ " "+ resultSet.getString(2)+" "+resultSet.getString(3)); } connection.close(); } catch (Exception e) { System.out.println(e); } } }
输出
获得的输出如下所示 -
Connected successfully...! Table records after Self Join...! 1 Learn PHP John Paul 3 JAVA Tutorial Sanjay
import mysql.connector #建立连接 connection = mysql.connector.connect( host='localhost', user='root', password='password', database='tut' ) cursorObj = connection.cursor() self_join_query = f"""SELECT a.ID, b.NAME as EARNS_HIGHER, a.NAME as EARNS_LESS, a.SALARY as LOWER_SALARY FROM CUSTOMERS a, CUSTOMERS b WHERE a.SALARY输出
以下是上述代码的输出 -
(4, 'Ramesh', 'Chaital', Decimal('1200.00')) (6, 'Khilan', 'Komal', Decimal('7000.00')) (4, 'Khilan', 'Chaital', Decimal('1200.00')) (1, 'Khilan', 'Ramesh', Decimal('4000.00')) (7, 'kaushik', 'Muffy', Decimal('10000.00')) (6, 'kaushik', 'Komal', Decimal('7000.00')) (5, 'kaushik', 'Hardik', Decimal('10000.00')) (4, 'kaushik', 'Chaital', Decimal('1200.00')) (2, 'kaushik', 'Khilan', Decimal('8000.00')) (1, 'kaushik', 'Ramesh', Decimal('4000.00')) (6, 'Hardik', 'Komal', Decimal('7000.00')) (4, 'Hardik', 'Chaital', Decimal('1200.00')) (2, 'Hardik', 'Khilan', Decimal('8000.00')) (1, 'Hardik', 'Ramesh', Decimal('4000.00')) (4, 'Komal', 'Chaital', Decimal('1200.00')) (1, 'Komal', 'Ramesh', Decimal('4000.00')) (6, 'Muffy', 'Komal', Decimal('7000.00')) (4, 'Muffy', 'Chaital', Decimal('1200.00')) (2, 'Muffy', 'Khilan', Decimal('8000.00')) (1, 'Muffy', 'Ramesh', Decimal('4000.00'))