mysql产品行的总和,其中数据标记在成本数据范围内

时间:2014-02-09 03:29:31

标签: mysql

我有三个表productcostaccount

CREATE TABLE `product` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `account_id` int(11) DEFAULT NULL,
  `name` varchar(255) NOT NULL DEFAULT '',
  `datestamp` date NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

CREATE TABLE `cost` (
  `account_id` int(11) NOT NULL,
  `amount` float NOT NULL,
  `datestamp` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `account` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8;

+-----+----------+-----------------+
| id  | name     | email           |
+-----+----------+-----------------+
| 101 | Acme Inc | jondoe@host.com |
+-----+----------+-----------------+

+------------+--------+------------+
| account_id | amount | datestamp  |
+------------+--------+------------+
|        101 |      5 | 2014-01-01 |
|        101 |     10 | 2014-01-03 |
|        101 |     15 | 2014-01-06 |
+------------+--------+------------+

+----+------------+---------+------------+
| id | account_id | name    | datestamp  |
+----+------------+---------+------------+
|  1 |        101 | Alfa    | 2014-01-01 |
|  2 |        101 | Bravo   | 2014-01-02 |
|  3 |        101 | Charlie | 2014-01-03 |
|  4 |        101 | Delta   | 2014-01-04 |
|  5 |        101 | Echo    | 2014-01-06 |
|  6 |        101 | Foxtrot | 2014-01-08 |
+----+------------+---------+------------+

我想返回每个单位成本和总数量 帐户将产品行与基于日期戳的成本相匹配 并按成本和帐户对这些进行分组,以便我可以加以总结。

就我的查询而言,这是我所坚持的尝试 将产品与合适的价格相匹配。

select
    a.id as account_id,
    count(p.id) as qty,
    c.amount as cost_per_unit,
    c.datestamp as cost_date,
    p.datestamp as product_date
from product p
left join account a on a.id = p.account_id
left join cost c on 1
where p.datestamp <is within right range based on cost date stamps>
group by c.amount, a.id
;

因此,如果2014-01-01的金额为5美元,2014-01-3和15美元的金额为10美元 在2014-01-06每个产品日期在10美元之前盖章 将是5美元,然后15美元将是10美元等等..

有关如何处理此问题的任何建议吗?

- 编辑 基于下面的答案,我能够得到我需要的东西

SELECT 
    a.id AS account_id,
    COUNT(p.id) AS qty,
    c1.amount AS cost_per_unit,
    c1.datestamp AS cost_date
FROM cost c1
    INNER JOIN account a ON a.id = c1.account_id
    LEFT JOIN cost c2 ON c2.datestamp = 
    (
        select datestamp 
        from cost 
        where account_id = a.id 
        and datestamp > c1.datestamp 
        order by datestamp ASC 
        LIMIT 1
    )
    LEFT JOIN product p ON p.datestamp >= c1.datestamp
WHERE p.datestamp < c2.datestamp OR c2.datestamp IS NULL
GROUP BY a.id, c1.amount
ORDER BY c1.datestamp ASC
;

1 个答案:

答案 0 :(得分:1)

在生产环境中这可能是非常低效的,但是为了您的修补享受,这个查询应该可以帮助您完成大部分工作。我知道你能够在你到目前为止做得很好的时候擦亮边缘:)

SELECT a.id AS account_id,
    COUNT(p.id) AS qty,
    c2.amount AS previous_cost_per_unit,
    c1.amount AS cost_per_unit,
    c1.datestamp AS cost_date,
    p.datestamp AS product_date
FROM product p
    INNER JOIN account a ON a.id = p.account_id
    INNER JOIN cost c1 ON c1.account_id = p.account_id AND c1.datestamp = p.datestamp
    LEFT JOIN cost c2 ON c2.datestamp = (SELECT MAX(datestamp) FROM cost WHERE account_id = c1.account_id AND datestamp < c1.datestamp)
GROUP BY account_id, product_date