[英]Mysql replace column value with other column value
我有2張桌子:
table: transaction:
====================
id billed_date amount
1 2016-09-30 5
2 2016-10-04 15
3 2016-10-06 10
table: report_date
====================
transaction_id report_date
1 2016-10-01
我想要:
然后我寫道:
首先:
SELECT
sum(t.amount),
CASE WHEN d.report_date IS NOT NULL THEN d.report_date ELSE t.billed_date END AS new_date
FROM
transaction t LEFT JOIN report_date d ON t.id = d.transaction_id
WHERE new_date BETWEEN '2016-10-01' AND '2016-10-30'
第二:
SELECT sum(amount) FROM
(SELECT t.amount,
CASE WHEN d.report_date IS NOT NULL THEN d.report_date ELSE t.billed_date END AS date
FROM transaction t LEFT JOIN report_date d ON t.id = d.transaction_id
) t
WHERE t.date BETWEEN '2016-10-01' AND '2016-10-30'
結果:
首先:
第二:
有人可以幫幫我嗎?
我終於在哥哥的幫助下找到了解決方案:
SELECT sum(amount)
FROM transaction t LEFT JOIN report_date d ON id = transaction_id
WHERE (report_date BETWEEN '2016-10-01' AND '2016-10-30') OR (report_date IS NULL AND billed_date BETWEEN '2016-10-01' AND '2016-10-30')
謝謝你關心我!
首先 - 部分
CASE WHEN d.report_date IS NOT NULL THEN d.report_date ELSE t.billed_date END
可寫得更短
COALESCE(d.report_date, t.billed_date)
或者作為
IFNULL(d.report_date, t.billed_date)
在第一個查詢中,您在WHERE子句中使用了列別名,這是不允許的。 您可以通過將別名后面的表達式移動到WHERE子句來修復它:
SELECT sum(t.amount)
FROM transaction t LEFT JOIN report_date d ON t.id = d.transaction_id
WHERE COALESCE(d.report_date, t.billed_date) BETWEEN '2016-10-01' AND '2016-10-30'
這與您自己的解決方案幾乎相同。
您的第二個查詢很慢,因為MySQL必須將子查詢結果(30K行)存儲到臨時表中。 試圖優化它,你將最終得到相同的解決方案。
但是,如果您在transaction.billed_date
和report_date.report_date
上有索引,則此查詢仍然無法使用它們。 要使用索引,可以將查詢拆分為兩部分:
包含報告的條目(將使用report_date.report_date
索引):
SELECT sum(amount)
FROM transaction t JOIN report_date d ON id = transaction_id
WHERE d.report_date BETWEEN '2016-10-01' AND '2016-10-30'
沒有報告的條目(將使用transaction.billed_date
索引):
SELECT sum(amount)
FROM transaction t LEFT JOIN report_date d ON id = transaction_id
WHERE d.report_date IS NULL AND t.billed_dateBETWEEN '2016-10-01' AND '2016-10-30'
兩個查詢都可以使用索引。 您只需要對結果求和,也可以將兩個查詢結合起來:
SELECT (
SELECT sum(amount)
FROM transaction t JOIN report_date d ON id = transaction_id
WHERE d.report_date BETWEEN '2016-10-01' AND '2016-10-30'
) + (
SELECT sum(amount)
FROM transaction t LEFT JOIN report_date d ON id = transaction_id
WHERE d.report_date IS NULL AND t.billed_dateBETWEEN '2016-10-01' AND '2016-10-30'
) AS sum_amount
填表table: report_date
缺少值table: transaction:
case?
SELECT id FROM report_date WHERE report_date BETWEEN '2016-10-01' AND '2016-10-30';
INSERT INTO report_date SELECT id, billed_date FROM transaction WHERE billed_date BETWEEN '2016-10-01' AND '2016-10-30' AND id NOT IN (ids_from previous_query);
SELECT sum(t.amount) FROM transaction LEFT JOIN report_date d ON (t.id = d.transaction_id) WHERE d.report_date BETWEEN '2016-10-01' AND '2016-10-30';
您的第二個查詢是正確的,無需重新編寫查詢。 但我有一件事要告訴你,在處理數千/數百萬條記錄時,這對你有很大的幫助。 我們也關注其他一些事情。 因為當您的表包含大量數據(數千和數百萬)記錄時,執行查詢需要時間。 它也可能導致鎖定,可能是查詢鎖或數據庫消失的問題。 要避免此問題,您只需創建一列的INDEX 。 在該列上創建INDEX ,它在where子句上執行/使用。 與您的情況類似,您可以在事務表中的billed_date列上創建INDEX 。 因為您的結果基於事務表。 有關如何在mysql / phpmyadmin中創建索引的更多詳細信息,請參閱此http://www.yourwebskills.com/dbphpmyadmintable.php鏈接。
在某些時候我遇到過同樣的問題然后我在列上創建了INDEX 。 現在我使用mysql處理數百萬條記錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.