理解mysql執行多表聯合查詢

閱讀目錄node

查詢多張表通常有以下鏈接方法:mysql

1)內鏈接:join, inner join
2)外鏈接:left join, left outer join, right join, right outer join, union;
3) 交叉鏈接:cross joinsql

join的含義是:用於多表中字段直接的聯繫。數據庫

基本語法以下:服務器

select * from table1 inner|left|right join table2 on conditiona

說明:table1 是指第一張表。table2是指第二張表。 on 後面的含義是:知足這個條件。app

join按照功能能夠分紅以下三類:ui

1) inner join(內鏈接,或叫等值鏈接):取得兩個表中存在鏈接匹配關係的記錄。
2)left join(左鏈接):取得左表(table1)徹底記錄,右表(table2)若是有條件相符合的記錄就匹配,不然爲null;
3) right join(右鏈接): 取得右表(table2)徹底記錄,左表(table1)若是有條件相符合的記錄就匹配,不然爲null;spa

咱們來看一個列子:命令行

以下是user1表和user2表中的數據以下所示:3d

一: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();
      }
    }); 
  }
});

而後運行結果以下:

相關文章
相關標籤/搜索