[英]How do I subtract two declared variables in MYSQL
我正在研究的問題如下:
與2003年相比,2004年每個月收到的金額有何不同?
這就是我到目前為止
SELECT @2003 = (SELECT sum(amount) FROM Payments, Orders
WHERE YEAR(orderDate) = 2003
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate));
SELECT @2004 = (SELECT sum(amount) FROM Payments, Orders
WHERE YEAR(orderDate) = 2004
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate));
SELECT MONTH(orderDate), (@2004 - @2003) AS Diff
FROM Payments, Orders
WHERE Orders.customerNumber = Payments.customerNumber
Group By MONTH(orderDate);
在輸出中,我得到了幾個月,但對於Diff,我得到了NULL,請幫助。 謝謝
我無法測試此數據,因為我沒有您的表格,但是請嘗試如下操作:
SELECT a.orderMonth, (a.orderTotal - b.orderTotal ) AS Diff
FROM
(SELECT MONTH(orderDate) as orderMonth,sum(amount) as orderTotal
FROM Payments, Orders
WHERE YEAR(orderDate) = 2004
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate)) as a,
(SELECT MONTH(orderDate) as orderMonth,sum(amount) as orderTotal FROM Payments, Orders
WHERE YEAR(orderDate) = 2003
AND Payments.customerNumber = Orders.customerNumber
GROUP BY MONTH(orderDate)) as b
WHERE a.orderMonth=b.orderMonth
我認為這是問題所在:
在@ 2003和@ 2004中,僅選擇總和。 即使按月分組,您仍然會選擇一列,即每一行都不會說它選擇的月份。 因此,當您嘗試減去SQL時,詢問@ 2003中的哪一行應從@ 2004中減去。
因此,我認為解決方案是選擇有總和的月份,然后根據該月份進行減法。
問:如何在MySQL中減去兩個聲明的變量。
答:您首先需要對它們進行聲明。 在MySQL存儲程序的上下文中。 但是這些變量名不會以at符號字符開頭。 以@符號開頭的變量名是用戶定義的變量。 而且沒有針對它們的DECLARE語句,我們無法將它們聲明為特定類型。
在SQL語句中減去它們
SELECT @foo - @bar AS diff
請注意,MySQL用戶定義的變量是標量值。
在SELECT語句中,使用Pascal樣式分配運算符:=將值分配給用戶定義的變量。 在SELECT語句的表達式中,等號是一個相等比較運算符。
作為如何在SQL SELECT語句中分配值的簡單示例
SELECT @foo := '123.45' ;
在OP查詢中,沒有完成分配。 等號是標量值與子查詢返回值的比較。 那些第一條語句是否在實際運行中而不會引發錯誤?
用戶定義的變量可能對於解決此問題不是必需的。
您要返回多少行? 聽起來您每個月要一個。 我們假設“年份”是指日歷年,例如1月到12月。 (我們可能想檢查一下這個假設。只是為了避免太晚才發現,這意味着從7月到6月的“財政年度”之類的東西。)
我們如何獲得月份清單? 看來您已經開始了。 我們可以使用GROUP BY或DISTINCT。
問題是……“收款額有什么區別……”
所以,我們希望收到的款項。 那就是我們收到的付款額嗎? 還是我們收到的訂單數量? (我們是在接受訂單並接收付款嗎?還是在下訂單並進行付款?)
當我想到“收到的金額”時,我在考慮收入。
鑒於我們只看到兩個表格,我想我們正在填寫訂單並收到付款。 (我可能想檢查一下,所以完成后,不會告訴我……“哦,我們的意思是收到的訂單數量”和/或“付款表是我們已付款的金額,我們收到的金額在其他表格中”
我們將假設有一列標識接收付款的“日期”,並且該列的數據類型為DATE(或DATETIME或TIMESTAMP),我們可以可靠地確定該日期的“月”已收到付款。
為了獲得我們在2003年收到付款的月份清單,...
SELECT MONTH(p.payment_received_date)
FROM payment_received p
WHERE p.payment_received_date >= '2003-01-01'
AND p.payment_received_date < '2004-01-01'
GROUP BY MONTH(p.payment_received_date)
ORDER BY MONTH(p.payment_received_date)
那應該給我們十二行。 除非我們在給定的月份沒有收到任何付款。 那么我們可能只會得到11行。 或10。或者,如果我們在2003年全年都沒有收到任何付款,我們將不會退回任何行。
為了提高性能,我們希望使用謂詞(WHERE子句中的條件引用裸列。使用適當的索引,MySQL將有效地使用索引范圍掃描操作。如果將列包裝在函數中,例如
WHERE YEAR(p.payment_received_date) = 2003
這樣,我們將強制MySQL在表中的每個翻轉行上評估該函數,然后比較該函數與文字的返回值。 我們寧願不這樣做,而在謂詞中引用裸列(WHERE子句中的條件)。
我們可以重復相同的查詢以獲取2004年收到的款項。我們要做的就是更改日期文字。
或者,我們可以將2003年和2004年的所有行匯總在一起,然后將其折疊為不同月份的列表。
我們可以使用條件聚合。 由於我們使用的是日歷年,因此我將使用YEAR()快捷方式(而不是范圍檢查)。 在這里,我們不關心在表達式中使用裸列。
SELECT MONTH(p.payment_received_date) AS `mm`
, MAX(MONTHNAME(p.payment_received_date)) AS `month`
, SUM(IF(YEAR(p.payment_received_date)=2004,p.payment_amount,0)) AS `2004_month_total`
, SUM(IF(YEAR(p.payment_received_date)=2003,p.payment_amount,0)) AS `2003_month_total`
, SUM(IF(YEAR(p.payment_received_date)=2004,p.payment_amount,0))
- SUM(IF(YEAR(p.payment_received_date)=2003,p.payment_amount,0)) AS `2004_2003_diff`
FROM payment_received p
WHERE p.payment_received_date >= '2003-01-01'
AND p.payment_received_date < '2005-01-01'
GROUP
BY MONTH(p.payment_received_date)
ORDER
BY MONTH(p.payment_received_date)
如果這是一個家庭作業問題,我強烈建議您自己解決此問題。 還有其他查詢模式將返回等效結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.