我有三个表product
,cost
和account
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
;
答案 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