oracle 隐式内部联接如何处理多个WHERE子句条件

gk7wooem  于 2023-04-20  发布在  Oracle
关注(0)|答案(3)|浏览(130)

使用显式内部联接,我们指定两个表中的公共列名,并选择在这些列中具有匹配值的记录。

SELECT Customers.customer_id, Customers.name, Orders.amount
FROM Customers
INNER JOIN Orders
ON Customers.customer_id = Orders.customer_id
WHERE Orders.amount >= 200;

但是对于隐式内部连接,我们只需要使用WHERE子句并指定要匹配的条件。所以我想了解连接如何处理多个条件,条件的顺序重要吗?
我问这个问题是因为我有两个表如下:

表1:客户

客户ID名称年龄
1约翰二十五
二十二

表2:订单

订单ID金额客户ID
1一百1
两百

orders表中的customer_id字段存储customers表中customer_id字段的值。不幸的是,我们对orders表中的customer_id字段没有任何外键约束。因此,如果您看到上面的orders表,customer_id=5customers表中不存在,当我运行下面的查询时,它返回下面的结果。

查询:-

SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
FROM Customers, Orders
WHERE Customers.customer_id = Orders.customer_id
AND Orders.amount >= 200;

结果:-

客户.customer_id订单.customer_idCustomers.nameOrders.amount
(空)(空)两百

Orders表中获取所有字段的数据,并将customers表中的字段数据作为空数据返回。但理想情况下,内部连接仅在两个表都匹配时才返回数据?
我可能误解了一些东西,并清除了我的基本知识。
谢谢你的帮助!

更新:

我真的很抱歉,但我只是注意到在代码中有**(+)**在右侧的WHERE子句,我被排除认为是没有用的,现在我知道它表示右外连接。现在查询结果对我来说是有意义的。

SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
FROM Customers, Orders
WHERE Customers.customer_id = Orders.customer_id (+)
AND Orders.amount >= 200;

感谢StackOverflow社区,你是最棒的!

ccgok5k5

ccgok5k51#

您的查询:

SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
FROM Customers, Orders
WHERE Customers.customer_id = Orders.customer_id
AND Orders.amount >= 200;

然后,可以用ANSI标准CROSS JOIN替换传统的逗号连接,并且与以下内容相同:

SELECT c.customer_id, o.customer_id, c.name, o.amount
FROM   Customers c CROSS JOIN Orders o
WHERE  c.customer_id = o.customer_id
AND    o.amount >= 200;

这反过来又与以下内容相同:

SELECT c.customer_id, o.customer_id, c.name, o.amount
FROM   Customers c
       INNER JOIN Orders o
       ON c.customer_id = o.customer_id
WHERE  o.amount >= 200;

这与您的第一个查询相同。
条件的顺序重要吗?
不想
当我运行下面的查询时,它返回下面的结果。
该结果是不可能的,因为Customers.customer_id = Orders.customer_id在输出中不是true,因此无法返回结果。

f5emj3cl

f5emj3cl2#

您的查询:

SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
FROM Customers, Orders
WHERE Customers.customer_id = Orders.customer_id
AND Orders.amount >= 200;

无法生成您显示的输出。这是一个内部连接,由于customers表中没有匹配的customer_id = 5,因此它也不会显示customer_id 5的订单记录。如果您想查看它,您需要一个外部连接:

SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
FROM Customers, Orders
WHERE Customers.customer_id(+) = Orders.customer_id
AND Orders.amount >= 200;

要回答您的特定问题,连接子句的顺序以及连接子句中列的顺序无关紧要。连接 predicate 与筛选 predicate 一样被处理,并按Oracle所希望的任何顺序进行计算,而不会更改结果。您的测试有问题。请再次验证SQL及其结果。

az31mfrm

az31mfrm3#

你运行自己的代码了吗?它没有显示你发布的结果。

SQLcl: Release 22.4 Production on Mon Apr 17 15:10:13 2023
koen>CREATE TABLE customers (customer_id,name,age)
  2  AS
  3  (
  4  SELECT 1,  'John', 25 FROM DUAL UNION ALL
  5  SELECT 2,  'Marry',    22 FROM DUAL 
  6* );

Table CUSTOMERS created.

koen>CREATE TABLE orders (order_id,amount,customer_id) 
  2  AS
  3  (
  4  SELECT 1,  100,    1 FROM DUAL UNION ALL
  5  SELECT 2,  200,    5 FROM DUAL
  6* );

Table ORDERS created.

您的查询-使用传统的连接语法。

koen>SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
  2  FROM Customers, Orders
  3  WHERE Customers.customer_id = Orders.customer_id(+)
  4* AND Orders.amount >= 200;

no rows selected

使用ANSI连接语法重写的同一查询

koen>SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
  2    FROM Customers
  3         JOIN Orders ON Customers.customer_id = Orders.customer_id
  4*   WHERE Orders.amount >= 200;

no rows selected

重写查询以生成显示的结果-使用传统的连接语法。

koen>SELECT Customers.customer_id, Orders.customer_id, Customers.name, Orders.amount
  2  FROM Customers, Orders
  3  WHERE Customers.customer_id(+) = Orders.customer_id
  4* AND Orders.amount >= 200;

   CUSTOMER_ID    CUSTOMER_ID NAME       AMOUNT 
______________ ______________ _______ _________ 
                            5               200

使用ANSI连接语法重写的同一查询

koen>SELECT customers.customer_id, orders.customer_id, customers.name, orders.amount
  2    FROM orders
  3         left outer JOIN customers ON customers.customer_id = orders.customer_id
  4*   WHERE orders.amount >= 200;

   CUSTOMER_ID    CUSTOMER_ID NAME       AMOUNT 
______________ ______________ _______ _________ 
                            5               200

相关问题