加入两个表,其中可能不存在连接

时间:2013-02-26 17:02:26

标签: sql oracle11g

我在为Oracle编写连接语句时遇到了一些问题。我想我想使用左连接,但我不是百分百肯定。

这是我的两张桌子

**VisibilityTable**
Industry
ProductID
Visibility
etc

**ItemTable**
ProductID
Other Info
etc

这是问题所在。我有~15个行业。每个行业都希望能够根据他们的偏好将产品(~15000)标记为公共或私有。如果您想查看特定行业的公共或私人产品,我可以查询。

我遇到的问题是,某个行业的产品被标记为公共或私有产品后,它不再出现在尚未标记的行业中。这是我到目前为止的查询:

SELECT v.*, NVL(b.VISIBILITY,'Not Marked') Visibility 
FROM ItemTable v 
LEFT OUTER JOIN VisibilityTable b ON b.ProductID = v.ProductID
WHERE (
(v.STATUS LIKE 'Filter' or 'Filter' LIKE 'All') AND 
(v.MODEL LIKE 'Filter' or 'Filter' LIKE 'All') AND 
(v.DUTY LIKE 'Filter' or 'Filter' LIKE 'All') AND 
(v.CERTIFICATION LIKE 'Filter' or 'Filter' LIKE 'All')
)

这适用于为我提供标记为“未标记”,“私有”,“公开”的项目,但我无法将其撤回到未在所选行业中标记的项目。

编辑:添加了完整的where子句。这是动态生成的,然后根据来自配置文件的值传入。

例如,ProductID 85322已被标记为Private for Industry EPGBio,但是当我选择Industry EPGMethane时,它不会显示为“未审核”。它显示为标记为私人。

1 个答案:

答案 0 :(得分:2)

我认为这是因为你过滤掉了没有出现在where子句中的结果。

当您在where子句中引用“b”表时,您隐式将left outer join更改为inner join。 (除非你碰巧正在做is null。)

将条件移至on子句。

我想我终于明白了。您试图区分b.Visibility为NULL和不存在的记录。为此,您需要case声明:

select v.*,
       (case when b.ProductId is null then 'Not Marked at All'
             when b.Visibility is null then 'Marked as NULL'
             else b.Visibility'
        end) as Visibility

我更改了生成的字符串以明确发生的事情。你可以随心所欲地制作它们。关键是使用连接键上的条件来判断记录是否存在,然后查看该值,以检查该值是否存在。