2011-02-24 68 views
0

我們的db將客戶訂單存儲在兩個表中:customerorders和customerorderlines。 在其他字段中,有一個customerorders.type字段,它確定(= 1或= 2) 該customerorder是發票還是信用證。Mysql查詢需要減去無法引用的字段

目前我們有一個報告,列出售出的單位數量,利潤等,但其目前的查詢,只顯示售出超過期限,即,它不扣除的積分數總檯,如果有的話。這裏是它的SQL和它產生的結果的一個例子:

(道歉隨後的大量查詢:))

SELECT l.name AS locationname 
, sr.name AS salesrepname 
, ct.name AS customertypename 
, c.name AS customername 
, c.id AS customer_id 
, c.code 
, s.name AS suppliername 
, p.description AS productname 
, p.id AS product_id 
, p.unitofmeasure 
, SUM(col.vatableprice) AS totalsales 
, SUM(col.vatprice) AS vat 
, SUM(col.quantity) AS totalitems 
, SUM(col.quantity * col.costprice) AS totalsalecost 
, SUM(col.vatableprice) - SUM(col.quantity * col.costprice) AS totalprofit 
,(
    SELECT SUM(col2.vatableprice) AS totalsales 
    FROM customerorders AS co2 
    LEFT JOIN customerorderlines AS col2 ON col2.customerorder_id = co2.id 
    LEFT JOIN customers AS c2 ON c2.id = co2.customer_id 
    LEFT JOIN locations AS l2 ON l2.id = c2.location_id 
    LEFT JOIN customertypes AS ct2 ON ct2.id = c2.customertype_id 
    LEFT JOIN salesreps AS sr2 ON sr2.id = c2.salesrep_id 
    LEFT JOIN products AS p2 ON p2.id = col2.product_id 
    LEFT JOIN suppliers AS s2 ON s2.id = p2.supplier_id 
    WHERE c.salesrep_id = c2.salesrep_id 
    AND co2.type = 2 AND p2.supplier_id = 179 
    AND co2.orderdate >= '2010-01-01 00:00:00' 
    AND co2.orderdate <= '2010-02-01 23:59:59' 
) AS credits 
,(
    SELECT SUM(col2.vatprice) AS totalvat FROM customerorders AS co2 
    LEFT JOIN customerorderlines AS col2 ON col2.customerorder_id = co2.id 
    LEFT JOIN customers AS c2 ON c2.id = co2.customer_id 
    LEFT JOIN locations AS l2 ON l2.id = c2.location_id 
    LEFT JOIN customertypes AS ct2 ON ct2.id = c2.customertype_id 
    LEFT JOIN salesreps AS sr2 ON sr2.id = c2.salesrep_id 
    LEFT JOIN products AS p2 ON p2.id = col2.product_id 
    LEFT JOIN suppliers AS s2 ON s2.id = p2.supplier_id 
    WHERE c.salesrep_id = c2.salesrep_id 
    AND co2.type = 2 
    AND p2.supplier_id = 179 
    AND co2.orderdate >= '2010-01-01 00:00:00' 
    AND co2.orderdate <= '2010-02-01 23:59:59' 
) AS creditsvat 

FROM customerorders AS co 
LEFT JOIN customerorderlines AS col ON col.customerorder_id = co.id 
LEFT JOIN customers AS c ON c.id = co.customer_id 
LEFT JOIN locations AS l ON l.id = c.location_id 
LEFT JOIN customertypes AS ct ON ct.id = c.customertype_id 
LEFT JOIN salesreps AS sr ON sr.id = c.salesrep_id 
LEFT JOIN products AS p ON p.id = col.product_id 
LEFT JOIN suppliers AS s ON s.id = p.supplier_id 
WHERE co.status_v = 5 
AND co.type = 1 
AND p.supplier_id = 179 
AND co.orderdate >= '2010-01-01 00:00:00' AND co.orderdate <= '2010-02-01 23:59:59' 
GROUP BY c.salesrep_id 

其中,在這種情況下(分組等是由應用程序代碼所確定的),生成一個「每個銷售代表」報告:

Rep | TotalItems | SalesValue| CostOfSales | Profit | VAT  | Credits | Credits(VAT) 
Rep1| 937  | £5796.49 | £3606.49 | £2190.00 | £1013.73 | £220.12 | £38.57 
Rep2| 1905  | £11695.09 | £7314.95 | £4380.14 | £2045.32 | £268.85 | £47.00 
Rep3| 1074  | £6346.61 | £3950.53 | £2396.08 | £1109.76 | £54.89 | £9.57 
Rep4| 2687  | £16129.42 | £10171.65 | £5957.77 | £2820.46 | £839.15 | £146.78 

那麼,問題在於,TOTALITEMS是所銷售項目的絕對數量(類型= 1的所有customerorders)。信用字段顯示類型= 2期間的項目的總成本,即返回。 TotalItems應該有從其中扣除的信用數量,所以一眼就可以看到實際上已售出的東西,當然所有其他領域也需要他們的信用卡對方也相互扣除,以便它們反映出售物品的正確金額。

起初,我認爲這將是對現有查詢的簡單修改,但後來發現我無法在選擇中引用子查詢別名,因此我使用JOIN(SELECT ....)重寫了整個查詢。加入(選擇.....)作爲學分,所以我可以從查詢頂部的SELECT引用sales.qty和credits.qty,但除非你做了小的查詢,否則那根本沒有規模。

這是多遠我得到:

(的確,我查詢了這裏不同的東西......這將是基本的查詢的最簡單形式:單品銷售/學分)

SELECT sr.name AS salesrepsname 
,l.name AS locationname 
,sup.name AS suppliername 
,p.description AS productname 
,sales.qty AS sold 
,credits.qty AS credits 
,sales.qty - credits.qty AS actualsold 
FROM 
customerorders co 
LEFT JOIN customerorderlines col ON col.customerorder_id = co.id 
LEFT JOIN customers c ON c.id = co.customer_id 
LEFT JOIN products p ON p.id = col.product_id 
LEFT JOIN salesreps sr ON sr.id = c.salesrep_id 
LEFT JOIN locations l ON l.id = c.location_id 
LEFT JOIN suppliers sup ON sup.id = p.supplier_id 
JOIN (SELECT SUM(col.quantity) AS qty, 
SUM(col.vatableprice) AS total FROM customerorderlines col 
LEFT JOIN customerorders co ON co.id = col.customerorder_id 
WHERE col.product_id = 27642 AND co.type = 1) 
AS sales 
JOIN (SELECT SUM(col2.quantity) AS qty FROM customerorderlines col2 
LEFT JOIN customerorders co2 ON co2.id = col2.customerorder_id 
WHERE col2.product_id = 27642 AND co2.type = 2) AS credits 
WHERE col.product_id = 27642 
GROUP BY c.salesrep_id 

所以我不得不承認我有點卡住了,並不是很熟悉mysql。

任何建議都非常歡迎,請隨時點我朝着先進的subquerying任何文學和加入,我應該去閱讀。

乾杯!

回答

1

我認爲你可能正在尋找的技巧是沿着這些線。在你想修正的任何給定的查詢/子查詢中,使用一些這樣的SQL,選擇所有行,不管它是發票還是信用註釋,並根據訂單/貨幣的方式總結一個正值或負值的值去:

SELECT 
    SUM(CASE WHEN co.type = 1 THEN col.quantity ELSE -col.quantity END) 
FROM 
    ... 

得到它嗎?您可以將所有訂單項都拿回來,但是當您完成這筆交易時,您將累計正信用和負借記金額,以便在一次操作中獲得實際總金額。

+0

謝謝。從來沒有考慮過使用CASE語句,但是你可能會想到一些東西。我們正在測試一些疑問。我會回報:-) – prevailrob 2011-02-24 10:19:42

+0

@prevailrob祝你好運!如果您想要在同一個查詢的相同結果行中報告不同的度量值,這種技術特別有用,例如,你可以計算總學分('SUM(CASE WHEN co.type = 1 THEN col。數量ELSE 0 END)'),總借項,總淨額,全部使用一個基本查詢。 – 2011-02-24 10:26:41

+0

只是想我會讓你保持最新狀態:即時通訊編輯與這些案件陳述和迄今如此好的查詢。我設法取消了這兩個子查詢,但目前遇到了一些問題(其超時)。稍微多點之後,我會在這裏發佈我的新查詢以供審查。乾杯! – prevailrob 2011-02-24 11:10:33