oracle语法到h2语法(+)连接表

时间:2015-10-02 20:58:43

标签: database oracle join h2

我有以下查询作为Oracle

   SELECT DISTINCT count(pa.payment_id)   FROM
    location c,    inventory e,
    inventory_stock es,    payment_client ep,
    payment pa,    currency cur,
    location s,    exchange_country exc,
    exchange_rate sso,
    exchange_hike so,
    exchange_margin sov  WHERE
    cur.outState = 'N' AND
    c.location_id = e.location_id AND
    e.inventory_id = ep.inventory_id AND
    e.inventory_stock_id = es.inventory_stock_id AND
    ep.client_id = pa.end_client AND
    pa.cur_id = cur.cur_id AND
    cur.location_id = s.location_id AND
    c.client_id  is not null  AND
    cur.cur_id = exc.cur_id(+) AND
    exc.exchange_id = sso.exchange_id(+) AND
    sso.account_id = so.account_id(+) AND
    so.option_name(+)  = 'PREMIUM' AND
    exc.exchange_id = sov.exchange_id(+) AND
    sov.name(+)  = 'VALUE';

现在我正在使用H2数据库,我得到的语法错误来自so.option_name(+)sov.name(+);我知道(+)是oracle的正确连接和左连接的方式,但是有没有办法把它转换成h2所以错误和语法是等价的吗?

1 个答案:

答案 0 :(得分:3)

是时候继续前进了。 Oracle不再推荐使用Oracle的旧外连接语法。 From the docs

  

Oracle建议您使用FROM子句OUTER JOIN语法而不是Oracle join运算符。使用Oracle连接运算符(+)的外连接查询受以下规则和限制的约束,这些规则和限制不适用于FROM子句OUTER JOIN语法[...]

如果您将(+)用法替换为outer join,那么您的查询不仅可以同时适用于Oracle和H2,而且也是整个应用程序的重要一步。

SELECT DISTINCT count(pa.payment_id) 
FROM location c
JOIN inventory e ON c.location_id = e.location_id
JOIN payment_client ep ON e.inventory_id = ep.inventory_id
JOIN inventory_stock es ON e.inventory_stock_id = es.inventory_stock_id
JOIN payment pa ON ep.client_id = pa.end_client
JOIN currency cur ON pa.cur_id = cur.cur_id
JOIN location s ON cur.location_id = s.location_id
LEFT JOIN exchange_country exc ON cur.cur_id = exc.cur_id
LEFT JOIN exchange_rate sso ON exc.exchange_id = sso.exchange_id
LEFT JOIN exchange_hike so 
  ON sso.account_id = so.account_id
  AND so.option_name = 'PREMIUM'
LEFT JOIN exchange_margin sov 
  ON exc.exchange_id = sov.exchange_id
  AND sov.name = 'VALUE'
WHERE c.client_id IS NOT NULL
AND cur.outState = 'N'

(+)转换为LEFT JOIN时的重要性在于您密切关注哪些谓词必须放入ON子句,哪些谓词在WHERE中正常条款。特别是,以下两个谓词必须包含在相关的左连接表ON子句中:

  • so.option_name(+) = 'PREMIUM'
  • sov.name(+) = 'VALUE'