Zvolte záznamy, které změnily své předchozí hodnoty

hlasů
0

Mám tabulku, kde bych registrovat historii ceně výrobků v katalogu (další tabulka).

V ceně jakéhokoliv produktu může měnit každou chvíli, takže musím zjistit jen to, co produkty změnily své ceny. Například mám tuto tabulku:

+----+--------------+-------+---------------------+
| 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 |
+----+--------------+-------+---------------------+

a já potřebuji tento výsledek:

+--------------+-------+---------------------+
| 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 |
+--------------+-------+---------------------+

a to jsou výjimky:

P02 nezměnila svou cenu, takže jsem ji ignorovat (ano, za stejnou cenu mohou být zaregistrovány vícekrát za sebou)

P03 mají pouze 1 registr, takže technicky nezměnila svou cenu, takže jsem ji ignorovat (to jsou velmi vzácné, ale některé výrobky se nikdy nemění jejich ceny)

P05 nezměnila svou cenu, takže jsem ji ignorovat

Dal jsem tyto údaje za účelem čtení snadno, ale technicky data mohou být v libovolném pořadí.

Posílám vám dotaz, takže nemusíte ztrácet příliš mnoho času:

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');

Díky předem.

Položena 10/10/2019 v 00:50
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
0

Není to přesná odpověď přesná, protože jsem očekávat, že výsledky na každém řádku, ale tato odpověď je dost dobrý a získat zaměstnání provádí:

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

A dává tento výsledek:

+----+--------------+-------+---------------------+----+--------------+-------+---------------------+
| 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 |
+----+--------------+-------+---------------------+----+--------------+-------+---------------------+
Odpovězeno 10/10/2019 v 22:00
zdroj uživatelem

hlasů
0

To vypadá jako přirozený případ užití pro funkci okna LAG(), k dispozici v MySQL 8.0:

SELECT product_code, price, price_date 
FROM (
    SELECT
        t.*,
        LAG(price) OVER(PARTITION BY product_code ORDER BY price_date) lag_price
    FROM PriceHistory t
) x WHERE price != lag_price

Demo na DB Fiddle - vypadá to, že existují discrepencies v očekávaných výsledků, které ukázaly, ale to se jeví jako správné výstupu na základě mého chápání vaší otázky:

| product_code | price | price_date          |
| ------------ | ----- | ------------------- |
| P01          | 15    | 2019-01-03 00:00:00 |
| P01          | 20    | 2019-01-05 00:00:00 |
| P01          | 15    | 2019-01-09 00:00:00 |
| P02          | 15    | 2019-01-06 00:00:00 |
| P04          | 25    | 2019-01-05 00:00:00 |
Odpovězeno 10/10/2019 v 00:57
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more