【问题标题】:MySQL get data of most recent related recordMySQL获取最近相关记录的数据
【发布时间】:2012-03-23 09:31:17
【问题描述】:

我有 2 个表格(就本问题而言)公司和发票。一个公司可以有多个发票,它们通过 company_id 自动增量关联。我希望从每个有发票的公司的最新发票中获取数据。
我不仅想要最近相关记录的日期,还想要来自该相关记录的各种数据。

我尝试了几种不同的方法,但我现在得到的查询很糟糕......这让我不得不在关系数据库中求助于这样的东西让我很痛苦。
这是查询...

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`

连接派生表中的数据然后将其拆分到父查询中是很糟糕的,但这是我发现实现我所寻找的唯一方法。

我试过了……

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 行 - 因为我相信派生表中的 LIMIT 实际上应用于父查询。很遗憾你不能做这样的事情,因为这将是一个易于阅读的解决方案。

对于我上面所说的可怕的串联,还有更好的选择吗?

【问题讨论】:

    标签: mysql join


    【解决方案1】:
    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
    );
    

    【讨论】:

    • 这是一个不错的解决方案,但与我上面的可怕方法相比似乎需要一段时间...... 76 秒 vs 0.0142。我在 invoices.company_id、invoices.invoice_id(主要)、invoices.invoice_stamp、company.company_id(主要)上有索引。我认为这是 WHERE...IN 子句中的子查询,它们似乎总是需要一段时间。感谢您的建议!
    • 在您的公司表中添加一个字段 (latest_invoice_id),并在发票表中的每次插入、更新或删除时通过触发器对其进行维护。
    • /* 这是一个我刚刚删除的愚蠢想法。 */
    【解决方案2】:

    我的建议是这样处理:

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

    如果您没有在命令中指定 ID,您可以选择所有公司 ID,并使用类似的命令对每个 ID 执行相同的操作:

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

    【讨论】:

    • 如果没有 LIMIT 子句,则返回系统中的所有发票。大多数公司都有超过 1 张发票,我只是希望返回每家公司的最新发票(以及发票表中的发票价值和各种其他字段)。此外,我确实需要构造查询FROM companies,因为我希望将其他联接添加到我的公司表中的其他相关数据中。干杯!
    猜你喜欢
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多