如何将隐式联接重写为显式联接?

时间:2018-09-06 13:31:22

标签: sql oracle

我在使用显式联接重写这些JOINS时遇到了一些麻烦。我正在尝试了解这是如何实现的。这是使用我继承的隐式联接的原始查询:

FROM prod.f31122 t,
       prod.f4801   wo,
       prod.f30008  r,
       prod.f0101   ab
WHERE t.wtdoco = wo.wadoco(+)
   and t.wtmmcu = wo.wammcu(+)
   and t.wtmmcu = r.iwmcu
   and t.wtan8 = ab.aban8

我尝试了以下操作,但是得到的结果集有所不同。计数相同,但结果集不正确(可能是我的分组未显示的问题)。这是我使用显式联接的翻译:

FROM prod.f31122 t      
JOIN prod.f4801 wo ON t.wtdoco = wo.wadoco
JOIN prod.f4801 wo ON wo.wammcu = t.wtmmcu 
JOIN prod.f30008 r ON t.wtmmcu = r.iwmcu 
JOIN prod.f0101 ab ON t.wtan8 = ab.aban8 

我只想确保从隐式连接到显式连接的翻译在逻辑上是正确的(出于我的教育和理解)。作为记录,我可以保留隐式联接,但我只是想更好地理解此过程。

3 个答案:

答案 0 :(得分:5)

FROM prod.f31122 t      
LEFT JOIN prod.f4801 wo ON t.wtdoco = wo.wadoco AND wo.wammcu = t.wtmmcu 
JOIN prod.f30008 r ON t.wtmmcu = r.iwmcu 
JOIN prod.f0101 ab ON t.wtan8 = ab.aban8 

您只加入一次wo,这两个加入条件出现在同一ON子句中,并且逻辑运算符AND位于它们之间。

LEFT JOIN也可以写为LEFT OUTER JOIN,而JOIN也可以写为INNER JOIN。我更喜欢这些较长的短语,因为它们更明确。

答案 1 :(得分:4)

这不是很正确。

  1. 使用表的一个实例和AND条件实现多个联接条件
  2. var theURL = "https://www.example.com?min_price=0&max_price=5000&brand=apple"; var parsedURL = new URL(theURL); // you should use window.location.search instead var searchParams = new URLSearchParams(parsedURL.search); var maxPrice = searchParams.get("max_price"); var minPrice = searchParams.get("min_price"); var brand = searchParams.get("brand"); // capitalize brand if it is in the query if (brand !== null) { brand = brand.toLowerCase() .split(' ') .map((s) => s.charAt(0).toUpperCase() + s.substring(1)) .join(' '); } // create the title based off which query parameters come through var title; if (maxPrice !== null) { title = `Phones Under Rs.${maxPrice}` if (brand !== null) { title = `${brand} Phones Under Rs.${maxPrice}` } } else if (brand !== null) { title = `${brand} Phones Price list 2018` } else { console.log(`other case came through: brand: ${brand} max_price: ${maxPrice} min_price: ${minPrice}`) } console.log(title);是外部联接的旧Oracle语法。单独使用JOIN的默认值为INNER JOIN,所以您需要更正它。

所以它应该像这样:

(+)

答案 2 :(得分:2)

这部分是错误的:

FROM prod.f31122 t      
JOIN prod.f4801 wo ON t.wtdoco = wo.wadoco
JOIN prod.f4801 wo ON wo.wammcu = t.wtmmcu 

您使用AND在单个联接上执行两项操作,而不是在两个单独的JOIN上执行。例如:

FROM prod.f31122 t      
LEFT JOIN prod.f4801 wo
    ON t.wtdoco = wo.wadoco and wo.wammcu = t.wtmmcu 

两次使用“ JOIN”将字面意义上的表两次分开连接,因此您将根据不同的连接条件获得所有字段的两个副本。

更正

每个@MathGuy和@AaronDietz评论由于问题中(+)的存在,我将其切换为LEFT JOIN。