我有一个表,用于在目录中注册产品价格的历史记录(另一个表)。
任何产品的价格都可以随时更改,因此我只需要确定上次更改价格的产品。例如,我有此表:
+----+--------------+-------+---------------------+
| id | product_code | price | price_date |
+----+--------------+-------+---------------------+
| 1 | P01 | 10.00 | 2019-01-01 00:00:00 |
| 2 | P01 | 15.00 | 2019-01-03 00:00:00 |
| 3 | P01 | 20.00 | 2019-01-05 00:00:00 |
| 4 | P01 | 15.00 | 2019-01-09 00:00:00 |
| 5 | P02 | 10.00 | 2019-01-04 00:00:00 |
| 6 | P02 | 15.00 | 2019-01-06 00:00:00 |
| 7 | P02 | 15.00 | 2019-01-07 00:00:00 |
| 8 | P03 | 15.00 | 2019-01-09 00:00:00 |
| 9 | P04 | 15.00 | 2019-01-01 00:00:00 |
| 10 | P04 | 15.00 | 2019-01-02 00:00:00 |
| 11 | P04 | 25.00 | 2019-01-05 00:00:00 |
| 12 | P05 | 15.00 | 2019-01-01 00:00:00 |
| 13 | P05 | 15.00 | 2019-01-02 00:00:00 |
+----+--------------+-------+---------------------+
我需要这个结果(如果它们相同,我需要每个产品的倒数第二个和最后一个价格,如果它们相同,则忽略该产品):
+--------------+-------+---------------------+
| product_code | price | price_date |
+--------------+-------+---------------------+
| P01 | 20.00 | 2019-01-05 00:00:00 |
| P01 | 15.00 | 2019-01-09 00:00:00 |
| P04 | 15.00 | 2019-01-02 00:00:00 |
| P04 | 25.00 | 2019-01-05 00:00:00 |
+--------------+-------+---------------------+
这是例外:
P02并未更改价格,因此我将其忽略(是的,同一价格可以连续多次注册)
P03只有1个寄存器,因此从技术上讲它没有更改价格,因此我将其忽略(这非常少见,但某些产品从未更改价格)
P05没改变价格,所以我忽略了它
我放置这些数据是为了便于阅读,但从技术上讲,数据可以是任何顺序。
我向您发送查询,这样您就不会浪费太多时间:
CREATE TABLE PriceHistory(
id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL,
product_code CHAR(3) NOT NULL,
price DECIMAL(5,2) NOT NULL,
price_date DATETIME NOT NULL,
PRIMARY KEY (id));
INSERT INTO PriceHistory(product_code, price, price_date) VALUES
('P01', 10, '2019-01-01'),
('P01', 15, '2019-01-03'),
('P01', 20, '2019-01-05'),
('P01', 15, '2019-01-09'),
('P02', 10, '2019-01-04'),
('P02', 15, '2019-01-06'),
('P02', 15, '2019-01-07'),
('P03', 15, '2019-01-09'),
('P04', 15, '2019-01-01'),
('P04', 15, '2019-01-02'),
('P04', 25, '2019-01-05'),
('P05', 15, '2019-01-01'),
('P05', 15, '2019-01-02');
谢谢。
答案 0 :(得分:0)
这不是精确的答案,因为我希望每行都有结果,但是这个答案足够好并且可以完成工作:
SELECT info1.*, info2.* FROM
(SELECT lasts.product_code, lasts.id AS last_id, penultimate.id AS penultimate_id FROM
(SELECT product_code, MAX(id) AS id FROM PriceHistory GROUP BY product_code HAVING COUNT(product_code) > 1) lasts
INNER JOIN
(SELECT product_code, MAX(id) AS id FROM PriceHistory WHERE id NOT IN (SELECT MAX(id) FROM PriceHistory GROUP BY product_code) GROUP BY product_code) penultimate
ON lasts.product_code = penultimate.product_code) relations
INNER JOIN PriceHistory info1 ON relations.last_id = info1.id
INNER JOIN PriceHistory info2 ON relations.penultimate_id = info2.id
WHERE info1.price != info2.price
并给出以下结果:
+----+--------------+-------+---------------------+----+--------------+-------+---------------------+
| id | product_code | price | price_date | id | product_code | price | price_date |
+----+--------------+-------+---------------------+----+--------------+-------+---------------------+
| 4 | P01 | 15.00 | 2019-01-09 00:00:00 | 3 | P01 | 20.00 | 2019-01-05 00:00:00 |
| 11 | P04 | 25.00 | 2019-01-05 00:00:00 | 10 | P04 | 15.00 | 2019-01-02 00:00:00 |
+----+--------------+-------+---------------------+----+--------------+-------+---------------------+