閱讀目錄
- 一:inner join(內連接)
- 二:left join(左連接)
- 三:right join(右連接)
- 四:cross join(交叉連接)
- 五:union操作
- 六:node+mysql 多表聯合查詢
查詢多張表一般有如下連接方法:
1)內連接:join, inner join
2)外連接:left join, left outer join, right join, right outer join, union;
3) 交叉連接:cross join
join的含義是:用於多表中字段直接的聯系。
基本語法如下:
select * from table1 inner|left|right join table2 on conditiona
說明:table1 是指第一張表。table2是指第二張表。 on 后面的含義是:滿足這個條件。
join按照功能可以分成如下三類:
1) inner join(內連接,或叫等值連接):取得兩個表中存在連接匹配關系的記錄。
2)left join(左連接):取得左表(table1)完全記錄,右表(table2)如果有條件相符合的記錄就匹配,否則為null;
3) right join(右連接): 取得右表(table2)完全記錄,左表(table1)如果有條件相符合的記錄就匹配,否則為null;
我們來看一個列子:
如下是user1表和user2表中的數據如下所示:
一:inner join(內連接)
基本語法如下:
select * from user inner join user2 on user.age = user2.age;
如上代碼的含義是:查詢user表和user2表(內連接) 通過on后面的條件查詢,user表中的age字段 等於 user2表中的age這個條件滿足的話,才會把兩個表中的數據都查詢出來的,否則的話,查詢數據就是空哦。如下所示:
二:left join(左連接)
基本語法如下:
select * from user left join user2 on user.age = user2.age;
如上代碼的含義是:如果user表中的age字段值 等於 user2表中的age字段的值的話,那么就會把所有的數據都查詢出來,如果該表中的字段age值不相等的話,那么user表中的記錄會全部查詢出來,user2表中的所有字段為null值。
如下所示:
三:right join(右連接)
基本語法如下:
select * from user right join user2 on user.age = user2.age;
和上面的 left join 的含義相反,就是說 如果條件相等的話,就會把兩張表的數據都查詢出來,如果不相等的話,就會把第二張表的數據查詢出來,第一張表的數據字段值為null.
如下所示:
四:cross join(交叉連接)
交叉連接,得到的結果是兩個表的乘積; 效果和 inner join 類似,如下所示:
五:union操作
select * from user left join user2 on user.username = user2.username union select * from user right join user2 on user.username = user2.username;
上面代碼的含義是:查詢user表和user2表,如果該兩張表的username值相等的話,使用left join(左鏈接) 和 right join(右連接),如果都相等的話,就把兩張表所有的數據查詢出來。否則的話,兩張表字段不相等的話,那么第一個條件 left join查詢后的數據就是 按照user表查詢出所有的數據,user2表中的數據字段值為null;union的含義的意思可以理解為或者的意思,我們可以理解它為or的意思,第二個條件是使用 right join 連接符,意思是如果username字段不相等的話,就按照第二張表的數據全部查詢出來,第一張表的所有字段查詢值為null。如下所示:
六:node+mysql 多表聯合查詢
在mysql模塊中,我們可以使用Connection對象的query方法的第一個參數編寫sql語句來執行多表聯合查詢,但是如果在sql語句中指定了相同的字段(比如相同的字段在不同的表中),那么在默認的情況下,后面的字段會覆蓋前面的字段查詢出來的數據。從而不是我們想要的結果。我們是想要把這兩張表的數據同時查詢出來。為了演示下,我們新建兩張表,一張是user表,該表有4個字段,分別是id,username, password, age; 另外一張表是user2表,該表有四個字段,分別是id,username,password,age等字段。如下所示:
我們現在使用Connection對象的query方法結合查詢這兩張表中的所有數據,查詢語句如下:
select * from user inner join user2 where user.age = user2.age;
因此所有的代碼如下所示:
const mysql = require('mysql'); /* createConnection方法創建一個表示與Mysql數據庫服務器之間連接的 Connection對象 */ const connection = mysql.createConnection({ host: 'localhost', port: 3306, database: 'my_db', user: 'root', password: '123456' }); /* connection 對象被創建之后,可以使用該對象的 connect方法建立mysql數據庫服務器之間的連接 */ connection.connect((err) => { if (err) { console.log(err); console.log('數據庫連接失敗'); } else { console.log('數據庫連接成功'); const sql = 'select * from user inner join user2 where user.age = user2.age'; connection.query(sql, (err, res) => { if (err) { console.log('查詢數據失敗'); } else { console.log(res); connection.end(); } }); } });
然后我們在命令行中,運行 node app.js 后,可以看到如下所示:
如上圖我們可以看到,查詢后的數據就是user2表中的數據,user1表的數據被覆蓋了,因為user表中的字段和user2表中的字段是一樣的,雖然在不同的表中,但是因為字段一樣,后面的user2表會把user表中的字段覆蓋掉。
解決方法有如下幾種:
1. 第一種是給sql語句重復的字段使用別名。這種方法比較繁瑣,因為如果表中有多個字段相同的話,要設置多個別名。這種方法不折騰。
2. 第二種方法為在query方法中使用 nestTables屬性,並將屬性值設置為true。因此會將兩個表中的數據以兩個對象的形式輸出來。如下sql語句改為如下:
{ sql: 'select * from user inner join user2 where user.age = user2.age', nestTables: true }
代碼如下:
const mysql = require('mysql'); /* createConnection方法創建一個表示與Mysql數據庫服務器之間連接的 Connection對象 */ const connection = mysql.createConnection({ host: 'localhost', port: 3306, database: 'my_db', user: 'root', password: '123456' }); /* connection 對象被創建之后,可以使用該對象的 connect方法建立mysql數據庫服務器之間的連接 */ connection.connect((err) => { if (err) { console.log(err); console.log('數據庫連接失敗'); } else { console.log('數據庫連接成功'); const sql = { sql: 'select * from user inner join user2 where user.age = user2.age', nestTables: true }; connection.query(sql, (err, res) => { if (err) { console.log('查詢數據失敗'); } else { console.log(res); connection.end(); } }); } });
然后我們運行結果如下所示:
如上圖可以看到,包含兩個對象user和user2,對象里面是各自的數據。
3. 第三種方法是為在query方法中使用nestTables屬性並將屬性值設定為一個分割字符,這會將被結合的兩張表中的數據以一個對象的形式輸出。該對象的屬性名 為 字段所屬表名+分割字符+字段名。
sql語句改為如下:
{ sql: 'select * from user inner join user2 where user.age = user2.age', nestTables: '_' }
所有代碼如下:
const mysql = require('mysql'); /* createConnection方法創建一個表示與Mysql數據庫服務器之間連接的 Connection對象 */ const connection = mysql.createConnection({ host: 'localhost', port: 3306, database: 'my_db', user: 'root', password: '123456' }); /* connection 對象被創建之后,可以使用該對象的 connect方法建立mysql數據庫服務器之間的連接 */ connection.connect((err) => { if (err) { console.log(err); console.log('數據庫連接失敗'); } else { console.log('數據庫連接成功'); const sql = { sql: 'select * from user inner join user2 where user.age = user2.age', nestTables: '_' }; connection.query(sql, (err, res) => { if (err) { console.log('查詢數據失敗'); } else { console.log(res); connection.end(); } }); } });
然后運行結果如下: