SQL包含没有数据的条目

SQL包含没有数据的条目,sql,oracle,join,Sql,Oracle,Join,以下是我正在使用的Oracle中的sql语句: SELECT FACILITY.fac_name , SUM(FEE_LOG.fee_amount) AS TOTAL_FEES FROM FACILITY , BOOK_DETAIL , TRANS_LOG , FEE_LOG , TRANS_TYPE WHERE FACILITY.fac_id = BOOK_DETAIL.fac_id AND BOOK_DETAIL.bkdt_id = TRANS_LOG.bkdt_id AND TRA

以下是我正在使用的Oracle中的sql语句:

SELECT FACILITY.fac_name
, SUM(FEE_LOG.fee_amount) AS TOTAL_FEES 
FROM FACILITY
, BOOK_DETAIL
, TRANS_LOG
, FEE_LOG
, TRANS_TYPE 
WHERE
FACILITY.fac_id = BOOK_DETAIL.fac_id 
AND BOOK_DETAIL.bkdt_id = TRANS_LOG.bkdt_id 
AND TRANS_LOG.trans_id = FEE_LOG.trans_id 
AND TRANS_LOG.trans_type_id = TRANS_TYPE.trans_type_id 
AND 
(
    TRANS_TYPE.trans_type_desc = 'LOST' 
    OR TRANS_TYPE.trans_type_desc = 'CHECKIN'
)
GROUP BY FACILITY.fac_name;
它的输出与此类似:

FACILITY          TOTAL_FEES
Facility 1        8.45
Facility 2        4.23
Facility 3        5.23
我有2个其他设施,但它们没有任何相关费用。我想将它们显示为0

因此,输出将如下所示:

FACILITY          TOTAL_FEES
Facility 1        8.45
Facility 2        4.23
Facility 3        5.23
Facility 4        0
Facility 5        0
ER图


对于
费用日志
表,使用
左联接
而不是隐式
内部联接

SELECT FACILITY.fac_name
     , SUM(FEE_LOG.fee_amount) AS TOTAL_FEES 
FROM FACILITY
JOIN BOOK_DETAIL ON FACILITY.fac_id = BOOK_DETAIL.fac_id 
JOIN TRANS_LOG ON BOOK_DETAIL.bkdt_id = TRANS_LOG.bkdt_id 
LEFT JOIN FEE_LOG ON TRANS_LOG.trans_id = FEE_LOG.trans_id 
JOIN TRANS_TYPE  TRANS_LOG.trans_type_id = TRANS_TYPE.trans_type_id 
WHERE TRANS_TYPE.trans_type_desc IN ('LOST', 'CHECKIN')
GROUP BY FACILITY.fac_name;

使用外部联接和on子句:

SELECT FACILITY.fac_name, SUM(nvl(FEE_LOG.fee_amount,0)) AS TOTAL_FEES
  FROM FACILITY
  left join BOOK_DETAIL
    on FACILITY.fac_id = BOOK_DETAIL.fac_id
  left join TRANS_LOG
    on BOOK_DETAIL.bkdt_id = TRANS_LOG.bkdt_id
  left join FEE_LOG
    on TRANS_LOG.trans_id = FEE_LOG.trans_id
  left join TRANS_TYPE
    on TRANS_LOG.trans_type_id = TRANS_TYPE.trans_type_id
   and TRANS_TYPE.trans_type_desc in ('LOST', 'CHECKIN')
 GROUP BY FACILITY.fac_name;
注意:如果您所指的这些设施没有任何费用,在BOOK_DETAIL或TRANS_LOG上有行,则可以用内部联接替换外部联接(仅适用于那些表)。任何表,在该表中可能存在或可能不存在相关记录,您必须使用外部联接。

尝试以下操作:

SELECT f.fac_name
, coalesce(SUM(fl.fee_amount),0) AS TOTAL_FEES 
FROM FACILITY AS f
INNER JOIN BOOK_DETAIL AS bd 
    ON bd.fac_id = f.fac_id
INNER JOIN TRANS_LOG AS tl
    ON tl.bkdt_id = bd.bkdt_id
LEFT OUTER JOIN FEE_LOG AS fl
    ON fl.trans_id = tl.trans_id
INNER JOIN TRANS_TYPE AS tt
    ON tt.trans_type_id = tl.trans_type_id 
WHERE tt.trans_type_desc in ('LOST' , 'CHECKIN')
GROUP BY f.fac_name;
注意:当您在
from
之后列出表,表之间带有逗号时,您实际上是在使用
交叉联接

将条件添加到
where
语句中,使一个表中的字段与另一个表中的字段相匹配时,联接将成为
内部联接

要从一个表中选择所有记录,以及从另一个表中可能存在或可能不存在的任何匹配项,您需要一个
外部联接

有三种类型:

  • 左外部联接
    您希望列出第一个表中的所有记录以及第二个表中的任何匹配记录
  • 右外部联接
    用于第二个记录中的所有记录,其中只有第一个记录中的匹配项
  • full outer join
    是两个表中的所有记录,如果存在匹配项,则彼此并排

您应该始终指定联接类型,而不是通过
where
子句/逗号来暗示联接类型,因为这会使您的意图更清晰,从而使代码更具可读性

您需要使用
左join
而不是where子句