2014-09-24 59 views
1

我試圖計算存儲在xcart_order_details中的活動銷售訂單中的庫存數量。我也只希望從x天內訂單中處理'P'或排隊'Q'狀態的股票以及股票類型與某些地點匹配的股票數量; C1股票,C2股票等等。使用連接和嵌套查詢計數數量

這在過去的xcart數據庫中過去比較簡單;

SELECT COUNT(`amount`) 
FROM `xcart_order_details` 
WHERE `productid` IN (
    SELECT `productid` 
    FROM `xcart_products` WHERE `orderid` IN 
    (SELECT `orderid` 
    FROM `xcart_orders` 
    WHERE `date` > ".$date_range." 
     AND (`status` = 'P' 
      OR `status` = 'Q')) 
    AND (LOWER(param01) = 'c1 stock' 
     OR LOWER(param01) = 'c2 stock' 
     OR LOWER(param01) = 'g stock' 
     OR LOWER(param01) = 'stock') 
    AND `productid` = ".$safe_prodid.") 

此查詢的工作。但是現在我們的庫存位置存儲在另一個名爲xcart_extra_field_values的表中,並且必須在fieldid = 5的位置檢索;

我試過使用連接從xcart_extra_field_values中獲取值字段,其中fieldid = 5,並嘗試執行我正在處理的上述查詢,但它不起作用。

SELECT COUNT(`a.amount`) 
FROM xcart_order_details a, 
    xcart_extra_field_values b 
WHERE a.productid IN (
    SELECT productid 
    FROM xcart_products WHERE orderid IN 
    (SELECT orderid 
    FROM xcart_orders 
    WHERE date > 1409529600 
     AND (status = 'P' 
      OR status = 'Q')) 
    AND (LOWER(b.value) = 'c1 stock' 
     OR LOWER(b.value) = 'c2 stock' 
     OR LOWER(b.value) = 'g stock' 
     OR LOWER(b.value) = 'stock') 
    AND (a.productid = b.productid) 
    AND (a.productid = 4169) 
    AND (b.fieldid = 5) 

遺憾的是此查詢不工作,我知道這是一個語法問題,但我得到的錯誤是沒有任何幫助。

任何人都可以闡明我做錯了什麼?

+0

你會得到什麼錯誤? – Arion 2014-09-24 11:51:02

+0

我得到了: 「#1064 - 你的SQL語法有錯誤;查看與你的MySQL服務器版本相對應的手冊,在第19行使用正確的語法」 「事後看來是有道理的,但當時還不清楚。 – 2014-09-24 12:05:56

+0

奇怪的是,順便說一下,你可以計算有數量的記錄。如果這是有意的,並且您不從表中選擇任何其他值,那麼如果您排除WHERE子句中的NULL('AND AND NOT IS NOT NULL)')並計數記錄('COUNT(*)) ')。如果金額永遠不會比計數記錄NULL(再次爲COUNT(*)'),而不是無論如何不能爲空的金額的非空發生。 (當然,如果你想計算總金額,你會* SUM *金額得到這個總數。) – 2014-09-24 12:30:06

回答

0

您缺少如何連接兩個表的條​​件。我們假設表xcart_extra_field_values中有一個xcart_order_details_id,然後使用它。

畢竟,你甚至不需要加入。你想從xcart_order_details結果,其中某些細節值的記錄存在:

SELECT COUNT(`amount`) 
FROM `xcart_order_details` 
WHERE `productid` IN 
(
    SELECT `productid` 
    FROM `xcart_products` 
    WHERE `orderid` IN 
    (
    SELECT `orderid` 
    FROM `xcart_orders` 
    WHERE `date` > ".$date_range." 
    AND `status` IN ('P','Q') 
) 
AND `productid` = ".$safe_prodid." 
AND EXISTS 
(
    SELECT * 
    FROM xcart_extra_field_values v 
    WHERE v.xcart_order_details_id = xcart_order_details.id 
    AND fieldid = 5 
    AND LOWER(param01) IN ('c1 stock','c2 stock','g stock','stock') 
); 

BTW:你看看有多少人爲了詳細記錄有多少?

+0

這可能是正確的,但看起來像一個完全不同的方式做我在做什麼,現在我的查詢得到了工作。我會看看這個方法,但看看它是否更有效率。 加入我的表的標準是在我的查詢(a.productid = b.productid) – 2014-09-24 11:56:20

+0

現在你提到它;-)我的查詢不完全是你原來的查詢。順便說一句,你也不會。我可以在所需的日期範圍和狀態下獲得所有記錄*和*有特定的庫存條目,當它具有所需的日期範圍和狀態*用於某個庫存條目時。當產品恰好在xcart_extra_field_values中爲想要的位置記錄了某個記錄時,您的查詢將獲取所需日期範圍和狀態中的記錄。我會再給你一個關於你的答案的評論。 – 2014-09-24 12:08:34

+0

是的,我已經糾正了我自己的答案。 xcart_extra_field_values將始終包含每個產品的條目。我基本上是從庫存位於特定倉庫位置的x天的活動客戶訂單中計算庫存。 – 2014-09-24 12:26:41

0

已解決。

SELECT COUNT(a.amount) 
FROM xcart_order_details a, 
    xcart_extra_field_values b 
WHERE a.productid IN 
    (SELECT productid 
    FROM xcart_products 
    WHERE orderid IN 
     (SELECT orderid 
      FROM xcart_orders 
      WHERE date > 1409529600 
      AND (status = 'P' 
       OR status = 'Q')) 
     AND (LOWER(b.value) = 'c1 stock' 
      OR LOWER(b.value) = 'c2 stock' 
      OR LOWER(b.value) = 'g stock' 
      OR LOWER(b.value) = 'stock')) 
     AND (a.productid = b.productid) 
     AND (a.productid = 4169) 
     AND (b.fieldid = 5) 

首先,我在我的查詢的末尾缺少一個支架,因爲我是嵌套在兩個IN查詢,我需要COUNT內刪除重音符圍繞a.amount,它不喜歡。當我並排查看我的問題時,我只注意到丟失的支架。

編輯:將我的連接移動到嵌套的IN子句之外,因爲嵌套它是沒有意義的。

+0

1.確保你連接正確。 xcart_order_details和xcart_extra_field_values不僅可以通過productid連接,是嗎? 2.進行交叉連接然後放棄IN子句中的連接結果記錄很奇怪。這是可能的,但不是很可讀。它看起來並不打算,所以第三個人可能會猜測查詢中存在缺陷。 3.您應該遠離容易出錯的逗號分隔連接語法,它在20年前由顯式連接(INNER JOIN,CROSS JOIN等)替代爲標準SQL。 – 2014-09-24 12:16:13

+0

extra_field_values表將始終包含productid上的匹配項,因此沒有任何內容被丟棄。 無論如何,Join不需要在IN子句中,我應該能夠通過將主IN子句的末尾移動到執行連接之前將其取出。 – 2014-09-24 12:20:44

+0

「丟棄」我的意思是:你交叉連接兩個表。如果每行都有1000行,則會得到100萬條結果記錄,但是會丟棄結果中的記錄。你用IN子句這樣做,好吧,但是在IN子句中,你使用來自外部(來自有問題的記錄)的值,這是非常罕見的。這是一個竅門,它很有效,但你必須小心,並知道你實際上在做什麼。它不被認爲是非常可讀或可維護的。 – 2014-09-24 12:25:31