Skip to main content

LEFT JOIN ON AND/WHERE

· 5 min read
Alec.Ji

Question

这两个SQL查询的结果相同吗?

SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId AND a.TableAId =1
SELECT * FROM TableA a LEFT JOIN TableB b ON b.AId =a.TableAId WHERE a.TableAId = 1

Test SQL

Creat Database

-- Create a new database called 'TEST' for XKA
-- Connect to the 'master' database to run this snippet
USE master
GO
-- Create the new database if it does not exist already
IF NOT EXISTS (
SELECT name
FROM sys.databases
WHERE name = N'TEST'
)
CREATE DATABASE TEST
GO

Creat Table

USE TEST

-- Create a new table called 'TableA' in schema 'TEST'
-- Drop the table if it already exists
IF OBJECT_ID('TEST.TableA', 'U') IS NOT NULL
DROP TABLE TEST.TableA
GO
-- Create the table in the specified schema
CREATE TABLE TableA
(
TableAId INT NOT NULL PRIMARY KEY,
-- primary key column
Code [NVARCHAR](50) NOT NULL,
Name [NVARCHAR](50) NOT NULL
-- specify more columns here
);
GO

-- Create a new table called 'TableB' in schema 'SchemaName'
-- Drop the table if it already exists
IF OBJECT_ID('TEST.TableB', 'U') IS NOT NULL
DROP TABLE TableB
GO
-- Create the table in the specified schema
CREATE TABLE TableB
(
TableBId INT NOT NULL PRIMARY KEY,
-- primary key column
AId INT NOT NULL,
Code [NVARCHAR](50) NOT NULL,
Name [NVARCHAR](50) NOT NULL
-- specify more columns here
);
GO

Creat Data

-- Insert rows into table 'TableA'
INSERT INTO TableA
VALUES
( -- first row: values for the columns in the list above
1, 'A', 'A'
),
( -- second row: values for the columns in the list above
2, 'B', 'B'
),
(3, 'C', 'C')
-- add more rows here
GO

-- Insert rows into table 'TableB'
INSERT INTO TableB
VALUES
( -- columns to insert data into
1, 1, 'C', 'C'
),
( -- first row: values for the columns in the list above
2, 1, 'D', 'D'
),
( -- second row: values for the columns in the list above
3, 2, 'E', 'E'
),
( -- second row: values for the columns in the list above
4, 2, 'D', 'D'
)
-- add more rows here
GO

Query Result

SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId 
TableAIdCodeNameTableBIdAIdCodeName
1AA11CC
1AA21DD
2BB32EE
2BB42DD
3CCNULLNULLNULLNULL
SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId AND a.code ='H'
TableAIdCodeNameTableBIdAIdCodeName
1AANULLNULLNULLNULL
2BBNULLNULLNULLNULL
3CCNULLNULLNULLNULL
SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId AND a.TableAId =1
TableAIdCodeNameTableBIdAIdCodeName
1AA11CC
1AA21DD
2BBNULLNULLNULLNULL
3CCNULLNULLNULLNULL
SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId AND b.AId = 1
TableAIdCodeNameTableBIdAIdCodeName
1AA11CC
1AA21DD
2BBNULLNULLNULLNULL
3CCNULLNULLNULLNULL
SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId WHERE a.TableAId = 1
TableAIdCodeNameTableBIdAIdCodeName
1AA11CC
1AA21DD
SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId WHERE b.AId =1
TableAIdCodeNameTableBIdAIdCodeName
1AA11CC
1AA21DD

ALL

IMAGE

Conclusion

连接多张表查询时会生成临时表,使用LEFT JOIN

  • ON 是生成临时表的条件,不管ON的结果是否为真,都会返回左边表的所有数据
  • AND 是在ON的基础上进行过滤,但是仍会返回左边表的所有数据
  • WHERE 是在临时表生成后,进行过滤,相当于对单表进行过滤

REF

Stackoverflow