2017-04-17 61 views
0

我有兩個表:「合併」完全外部連接而不是?

+-----------------------+ 
| 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)。

現在,我想構建一個網頁,將顯示用戶還沒有采取的新訂單(應該是orderIds沒有記錄在該用戶的userId下的orderTaken表中的訂單),以及用戶已經使用orderStatus顯示的順序,但是orderStatus不是4或5,按orderCreationTime DESC組合(如果我沒有OrderTakenTime但是讓我們保持這種方式,也許沒有意義),就像:

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 

自此之後返回將消除將訂單還沒有被記錄在orderTaken B.我的新訂單」表以前也嘗試了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; 

這個查詢的作品,但它不會在返回的表有場orderStatus從orderTaken B中。我想在此查詢後添加另一個JOIN orderTaken B子句以從B中獲取字段,但我認爲這不是寫好查詢的好方法。

我只是想結合「不在」和「全加入」。有人可以幫我嗎?謝謝!

回答

0

你似乎想找到未分配給用戶(沒有在orderTaken一個相關的記錄),加上分配給一個用戶的那些在orders的記錄,但在orderStatus不4或5.

然後不需要完整的外部聯接,因爲在orders中沒有相關記錄的orderTaken中將沒有記錄。甲Left inner join可以用來從orders找到所有的記錄,一個on子句將包括來自orderTaken從相關記錄數據,然後將where子句可以過濾掉由其他用戶執行的命令,或者在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 
+0

謝謝泰耶!這正是我想要的!我正在考慮使用LEFT JOIN,但我只是不知道「IS NULL」子句。這是我從你那裏學到的關鍵。再次感謝您解決我的問題! :D – Hang

+0

我現在更正了表名(orderTaken,拼寫爲orderStatus)。 –

+0

這使得它更加精確。再次感謝Terje! – Hang

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 
+0

是的Jben感謝您的改進答案!是的Terje提供了錯誤的表名,但邏輯正確,而你的回答只是使它成爲完美的110%!並且感謝你選擇特定用戶的提示!D:你真是太棒了! – Hang

+0

Hi @ j-bin其實我覺得這段代碼可能有錯誤?試圖在多個用戶同時接受訂單的情況下測試此查詢se店主帳戶創建一個新的新訂單,然後運行這個查詢我可以看到這個新訂單在每個用戶的頁面上,但是在其中一個用戶接受訂單後,說userId = 3的那個,然後其他用戶喜歡userId = 2或4將不會再次看到此訂單,但是此訂單將繼續顯示在userId = 3的頁面上,並且狀態顯示正確。我試圖通過採取ot.user_id =來修改代碼到where子句並使其如下所示: – Hang

+0

WHERE o.isClosed = 0 AND ot.user_id = 2/4 AND((ot.orderStatus IS NULL)OR(ot.orderStatus NOT IN(4,5))),但是這仍然返回一個空數組。我也嘗試把這個user_id的限制放在沒有運氣的任何其他地方。你還可以看看它,我真的很感激它! :D – Hang