"结合" FULL OUTER JOIN而不是In?

时间:2017-04-17 10:44:09

标签: mysql join where notin full-outer-join

我有两张桌子:

+-----------------------+
| Tables_in_my_database |
+-----------------------+
| orders                | 
| orderTaken            | 
+-----------------------+

在订单中,有属性

orderId, orderName, isClosed and orderCreationTime. 

在orderTaken中,有属性

userId, orderId and orderStatus. 

让我们说什么时候

orderStatus = 1 --> the customer has taken the order
orderStatus = 2 --> the order has been shipped
orderStatus = 3 --> the order is completed
orderStatus = 4 --> the order is canceled
orderStatus = 5 --> the order has an exception

基本上我的项目运行机制如下:具有唯一userId的用户将能够从网页下订单,其中每个订单也有自己唯一的orderId。获取后,orderTaken表将记录userId,orderId并初始设置orderStatus = 1.然后商店根据各种情况更新orderStatus。一旦商店更新了isClosed = 1,那么无论用户是否接受该订单,都不会显示该订单(没有意义,但它只是查询中的isClosed == 0)。

现在,我想构建一个网页,该网页将显示用户尚未采取的新订单(应该是订单,这些订单的订单不会记录在此用户下的orderTaken表中&#39 ; s userId),以及用户已经使用orderStatus显示的订单但是orderStatus IS不是4或5,按orderCreationTime DESC分组(是的,如果我没有订单,则可能没有意义但是让我们#39; s保持这种方式),如:

OrderId 4
Order Name: PetPikachu
orderStatus = 1
CreationTime: 5am

OrderId 3
Order Name: A truck of hamsters
orderStatus = 3
CreationTime: 4am

OrderId 2
New order
Order Name: Macbuk bull
CreationTime: 3am

OrderId 1
Order Name: Jay Chou's Album
orderStatus = 2
CreationTime: 2am

我根据我所学到的知识编写了这个查询:

SELECT * FROM orders A WHERE A.isClosed == '0' FULL OUTER JOIN orderTaken B  WHERE B.userId = '4' AND (B.orderStatus<>'4' OR B.orderStatus<>'5') ORDER BY A.orderCreationTime DESC;

显然这个查询不起作用,但我害怕有一个

ON A.orderId = B.orderId

从那时起,返回的表将消除orderId未按顺序记录的新订单。我还尝试过NOT IN子句,如

SELECT * FROM orders A WHERE A.isClosed = '0' AND A.orderId NOT IN (SELECT orderId FROM orderTaken B WHERE B.userId = '$userId' AND (B.orderStatus='4' OR B.orderStatus='5')) ORDER BY creationTime DESC;

此查询有效,但在返回的表中没有来自orderTaken B的字段orderStatus。我想在此查询之后添加另一个JOIN orderTaken B子句以从B获取字段但我认为这不是编写查询的好方法。

我只是想结合一起&#34; NOT IN&#34;和#34;完全加入&#34;。有人可以帮帮我吗?谢谢!

2 个答案:

答案 0 :(得分:1)

就像@ terje-d所说,你需要的是LEFT JOIN。使用原始表名更新了它并修复了$userId过滤器。

  • 适用于所有未结订单和不完整订单。
   SELECT o.`orderId`, 
          o.`orderName`,
          ot.`orderStatus`,
          o.`orderCreationTime`
     FROM orders o 
LEFT JOIN orderTaken ot
       ON o.orderId = ot.orderId
    WHERE o.isClosed = 0
      AND (
            ot.orderId IS NULL
         OR ot.orderStatus NOT IN (4,5)
      )
 ORDER BY o.`orderCreationTime` DESC
  • 适用于特定用户的所有未结订单和不完整订单
   SELECT o.`orderId`, 
          o.`orderName`,
          ot.`orderStatus`,
          o.`orderCreationTime`
     FROM orders o 
LEFT JOIN orderTaken ot
       ON o.orderId = ot.orderId
    WHERE o.isClosed = 0
      AND ( ot.orderStatus IS NULL
         OR (
                ot.user_id = ?
            AND ot.orderStatus NOT IN (4,5)
         )
      )
 ORDER BY o.`orderCreationTime` DESC

答案 1 :(得分:0)

您似乎想要在orders中找到未分配给用户的记录(orderTaken中没有相关记录)加上那些被分配给用户,但orderStatus不是4或5。

然后不需要完全外部联接,因为orderTaken中没有orders中没有相关记录的记录。可以使用Left inner join查找orders中的所有记录,on子句将包含来自orderTakenwhere子句的相关记录中的数据然后过滤掉其他用户的订单,或者orderStatus是4或5的地方:

SELECT o.*, ot.userID, ot.orderStatus
FROM orders o
LEFT JOIN orderTaken ot
ON ot.orderID = o.orderID
WHERE o.isClosed = 0
AND (ot.userID IS NULL OR ot.userID = $userID AND ot.orderStatus NOT IN (4,5))
ORDER BY o.creationTime DESC