SQL包含没有数据的条目
以下是我正在使用的Oracle中的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
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子句