2012-03-05 103 views
0

我有2個表格(針對這個問題)公司和發票。一個公司可以有多個發票,並且它們通過一個company_id自動遞增相關聯。我正在尋找每個有發票的公司的最新發票數據。
我不只想要最近的相關記錄的日期,而是來自相關記錄的各種數據。MySQL獲取最近相關記錄的數據

我嘗試了幾種不同的方法,但我現在的查詢是可怕的......它讓我痛苦的不得不訴諸於關係數據庫中這樣的事情。
這裏的查詢......

SELECT `companies`.`company_name`, `invoices_latest`.`data`, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`invoices_latest`.`data`, '~', 1), '~', -1) AS `last_invoice_stamp`, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`invoices_latest`.`data`, '~', 2), '~', -1) AS `last_invoice_id`, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`invoices_latest`.`data`, '~', 3), '~', -1) AS `last_invoice_reference`, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`invoices_latest`.`data`, '~', 4), '~', -1) AS `last_invoice_amount` 
FROM `companies` 
INNER JOIN 
(
SELECT `company_id`, MAX(CONCAT_WS('~', `invoice_stamp`, `invoice_id`, `reference`, CONCAT_WS(' ', `currency`, FORMAT(`amount`, 2)))) AS `data` 
FROM `invoices` 
GROUP BY `invoices`.`company_id` 
) AS `invoices_latest` ON `companies`.`company_id`=`invoices_latest`.`company_id` 
WHERE `invoices_latest`.`data` IS NOT NULL 
ORDER BY `companies`.`company_name`

連接Data派生表,然後父查詢中分裂出來是可怕的,但它是我發現要達到什麼我正在尋找的唯一途徑。

我想這...

SELECT `companies`.`company_id`, `companies`.`company_name`, `invoices_latest`.`invoice_id`, FROM_UNIXTIME(`invoices_latest`.`invoice_stamp`) 
FROM `companies` 
LEFT JOIN (
SELECT `company_id`, `invoice_id`, `invoice_stamp` 
FROM `invoices` 
ORDER BY `invoice_stamp` DESC 
LIMIT 0, 1 
) AS `invoices_latest` ON `companies`.`company_id`=`invoices_latest`.`company_id` 
WHERE `invoices_latest`.`invoice_id` IS NOT NULL

但預期它不工作,只返回1行 - 因爲我相信在派生表規定的實際適用於父查詢。這是一個恥辱,你不能這樣做,因爲這將是一個易於閱讀的解決方案。

有沒有更好的選擇,我上面已經進行了可怕的連接?

回答

0
select company,*, invoice.* 
from company, invoice 
where company.company_id = invoice.company_id 
and (invoice.company_id, invoice.date) in (
    select company_id, max(date) from invoices group by company_id 
); 
+0

這是一個很好的解決方案,但似乎需要一個年齡相比,我上面的可怕方法... 76秒vs 0.0142。我有關於invoices.company_id,invoices.invoice_id(主要),invoices.invoice_stamp,companies.company_id(主要)的索引。我認爲這是WHERE ... IN子句中的子查詢,它們似乎總是需要一段時間。感謝您的建議! – batfastad 2012-03-05 23:59:20

+0

將一個字段(latest_invoice_id)添加到公司表中,並通過發票表中的每個插入,更新或刪除操作通過觸發器對其進行維護。 – 2012-03-06 09:27:07

+0

/*這是我剛剛刪除的一個愚蠢的想法。 */ – 2012-03-06 13:47:53

0

我的建議是接近它是這樣的:

SELECT * FROM `invoice` WHERE `company_id`=ID ORDER BY `date` DESC LIMIT 25; 

,如果你沒有在命令中指定的ID,您可以選擇所有公司的ID,做同樣的事情,每個幾乎與一個類似的命令:

SELECT * FROM `invoice` WHERE `company_id` IN(SELECT `company_id` FROM `companies`) ORDER BY `date` DESC LIMIT 25; 
+0

如果沒有LIMIT子句,則返回系統中的所有發票。大多數公司有超過1張發票,我只是想要爲每家公司返回最近的發票(以及發票值和發票表中的其他各個字段)。此外,我確實需要構建查詢「FROM companies」,因爲我正在尋找其他連接添加到來自公司表的其他相關數據。乾杯! – batfastad 2012-03-06 00:05:18