强制为左联接返回空值

时间:2019-02-26 15:55:37

标签: sql sql-server

我有三个具有以下结构的表

CUSTOMER
OwnerID    | ProfileID (PK)| Name    | Surname    | Address
Owner1       Profile1       John      Brown        some address
Owner1       Profile2       John      Brown        some address
Owner1       Profile3       John      Brown        some address
Owner2       Profile4       Charles   Snow         some address
Owner2       Profile5       Charles   Snow         some address
Owner2       Profile6       Charles   Snow         some address
Owner3       Profile7       Edward    Glork        some address
Owner3       Profile8       Edward    Glork        some address

LOANS
LoanID (PK)| ProfileID    | Amount    | Duration
Loan1       Profile1       5000        31
Loan2       Profile2       1000        31
Loan3       Profile4       4000        31
Loan4       Profile4       10000       31
Loan5       Profile5       600         31
Loan6       Profile6       800         31

PAYMENTS
PaymentID (PK)| LoanID    | Amount    | Date
Payment1        Loan1       100         01-12-2017
Payment2        Loan1       100         01-14-2017
Payment3        Loan2       200         02-12-2017
Payment4        Loan2       300         02-15-2017
Payment5        Loan1       175         03-04-2017
Payment6        Loan2       235         03-04-2017
Payment7        Loan1       345         04-05-2017

此处是SQL语句

SELECT 
c.OwnerID as ID,
c.ProfileID as Prof,
c.Name,
c.Surname,
l.Amount as Credit_Amount,
p.Amount as Debit_Amount,
p.Date as Debit_Date
from CUSTOMER c
left join LOANS l on l.ProfileID = c.ProfileID
left join PAYMENTS p on p.LoanID = l.LoanID
where p.Amount > 199

我期望的输出是

ID    | Prof    | Name    | Surname    | Credit_Amount    | Debit_Amount    |Debit_Date
Owner1  Profile1  John      Brown        5000               null             null
Owner1  Profile1  John      Brown        5000               null             null
Owner1  Profile2  John      Brown        1000               200             02-12-2017
Owner1  Profile2  John      Brown        1000               300             02-15-2017
Owner1  Profile1  John      Brown        5000               null             null
Owner1  Profile2  John      Brown        1000               235             03-04-2017
Owner1  Profile1  John      Brown        5000               345             04-05-2017
Owner2  Profile4  Charles   Snow         4000               null             null
Owner2  Profile4  Charles   Snow         10000              null             null
Owner2  Profile6  Charles   Snow         800                null             null
Owner3  Profile7  Edward    Glork         null               null             null
Owner3  Profile8  Edward    Glork         null               null             null

我得到的输出是

ID    | Prof    | Name    | Surname    | Credit_Amount    | Debit_Amount    |Debit_Date
Owner1  Profile2  John      Brown        1000               200             02-12-2017
Owner1  Profile2  John      Brown        1000               300             02-15-2017
Owner1  Profile2  John      Brown        1000               235             03-04-2017
Owner1  Profile1  John      Brown        5000               345             04-05-2017

那么,我在SQL逻辑中究竟会误解什么?当我们使用左连接时,是否必须向右填充Aint空值?我该如何纠正SQL语句,以便在客户不匹配WHERE子句的情况下获得CUSTOMERS表的所有记录以及其余字段的空值?

1 个答案:

答案 0 :(得分:5)

将您的where p.Amount > 199移至ON

SELECT c.OwnerID AS ID,
       c.ProfileID AS Prof,
       c.Name,
       c.Surname,
       l.Amount AS Credit_Amount,
       p.Amount AS Debit_Amount,
       p.Date AS Debit_Date
FROM CUSTOMER c
     LEFT JOIN LOANS l ON l.ProfileID = c.ProfileID
     LEFT JOIN PAYMENTS p ON p.LoanID = l.LoanID
                         AND p.Amount > 199;

当使用LEFT JOIN引用表中的列时,除非您处理空值,否则它将LEFT JOIN转换为隐式INNER JOIN。相反,在ON中处理这样的子句会更容易,因为它会过滤其中的结果,但是仍然找不到“正确”表中的数据,找不到合适的行。