Свинец с суммой в mysql - PullRequest
0 голосов
/ 16 марта 2020

Это схема БД

CREATE TABLE `visita_prodotto`  (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
   `prezzo` int(15) UNSIGNED NULL DEFAULT NULL COMMENT 'price',
  `id_visita` int(10) UNSIGNED NOT NULL COMMENT 'visit id');


  CREATE TABLE `visita`  (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `id_campagna` int(10) UNSIGNED NOT NULL COMMENT 'project',
  `dataorainizio` datetime(0) NOT NULL COMMENT 'start date');

INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (53, 8, 5000);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (54, 8, 8000);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (55, 9, 4000);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (56, 9, 3000);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (66, 11, 5544);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (71, 12, 7500);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (77, 13, 5433);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (85, 17, 7200);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (89, 15, 4500);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (94, 16, 3200);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (99, 16, 5800);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (104, 16, 99999);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (107, 22, 7500);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (111, 22, 129999);
INSERT INTO `visita_prodotto`(`id`, `id_visita`, `prezzo`) VALUES (113, 22, 99999);

INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (8, '2020-02-12 15:23:00', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (9, '2020-02-14 01:59:45', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (11, '2020-02-19 14:27:17', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (12, '2020-02-19 15:43:42', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (13, '2020-02-20 14:02:35', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (15, '2020-02-25 15:58:00', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (16, '2020-02-21 15:59:00', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (17, '2020-02-21 16:13:00', 5);
INSERT INTO  `visita`(`id`, `dataorainizio`, `id_campagna`) VALUES (22, '2020-03-12 15:11:00', 5);

У меня есть этот запрос

 SELECT YEAR(v.dataorainizio) AS Year, WEEK(v.dataorainizio) AS Week, ROUND(sum(prezzo)/1000,2) as total_price
FROM visita_prodotto vp 
join visita v on vp.id_visita=v.id
where YEARWEEK(v.dataorainizio,1)<=YEARWEEK(NOW(),1) and  YEARWEEK(v.dataorainizio,1)>=YEARWEEK(NOW(),1)-10 and v.id_campagna=5
GROUP BY Year, Week
order by Week desc

, который дает такой результат

YEAR    WEEK TOTAL_PRICE
2020    10   237,50
2020    8    4,50
2020    7    134,68
2020    6    20,00

Я хотел бы получить

YEAR    WEEK TOTAL_PRICE DIFFERENCE
2020    10   237,50        233
2020    8    4,50          -130,18
2020    7    134,68        114,68
2020    6    20,00

Я пробовал с суммой (лидерством), но безуспешно ..

структура соответствующих таблиц

первая таблица visita_prodotto

 id      id_visita                 prezzo
 int pk  int(related to visita)    int

таблица соединений Виза:

id     dataorainizio id_campagna
int pk datetime      int

Я использую MARIADB 10.2

Кто-нибудь может мне помочь?

спасибо

Ответы [ 4 ]

1 голос
/ 16 марта 2020

Вы можете использовать оконную функцию LEAD () следующим образом:

SELECT 
  YEAR(v.dataorainizio) AS Year, 
  WEEK(v.dataorainizio) AS Week, 
  ROUND(SUM(prezzo)/1000,2) as total_price,
  LEAD(ROUND(SUM(prezzo)/1000,2)) OVER (ORDER BY YEAR(v.dataorainizio), WEEK(v.dataorainizio)) - ROUND(SUM(prezzo)/1000,2) difference
FROM visita_prodotto vp 
JOIN visita v ON vp.id_visita=v.id
WHERE YEARWEEK(v.dataorainizio,1)<=YEARWEEK(NOW(),1) AND YEARWEEK(v.dataorainizio,1)>=YEARWEEK(NOW(),1)-10 AND v.id_campagna=5
GROUP BY Year, Week
ORDER BY Week desc

Кажется, что MariaDB не поддерживает вложение агрегатных функций внутри оконных функций, поэтому сделайте это:

WITH cte AS (
  SELECT 
    YEAR(v.dataorainizio) AS Year, 
    WEEK(v.dataorainizio) AS Week, 
    ROUND(SUM(prezzo)/1000,2) AS total_price,
    ROW_NUMBER() OVER (ORDER BY YEAR(v.dataorainizio) DESC, WEEK(v.dataorainizio) DESC) AS rn
  FROM visita_prodotto vp 
  JOIN visita v ON vp.id_visita=v.id
  WHERE YEARWEEK(v.dataorainizio,1)<=YEARWEEK(NOW(),1) AND YEARWEEK(v.dataorainizio,1)>=YEARWEEK(NOW(),1)-10 AND v.id_campagna=5
  GROUP BY Year, Week
)
SELECT c1.Year, c1.Week, c1.total_price,
  c1.total_price - c2.total_price AS difference
FROM cte c1 LEFT JOIN cte c2
ON c2.rn = c1.rn + 1
ORDER BY c1.Year DESC, c1.Week DESC

Смотрите демо . Результаты:

> Year | Week | total_price | difference
> ---: | ---: | ----------: | ---------:
> 2020 |   10 |      237.50 |     233.00
> 2020 |    8 |        4.50 |    -130.18
> 2020 |    7 |      134.68 |     114.68
> 2020 |    6 |       20.00 |     null
1 голос
/ 16 марта 2020
WITH cte AS ( SELECT YEAR(v.dataorainizio) AS Year, 
                     WEEK(v.dataorainizio) AS Week, 
                     ROUND(sum(prezzo)/1000,2) as total_price
              FROM visita_prodotto vp 
              join visita v on vp.id_visita=v.id
              where YEARWEEK(v.dataorainizio,1)<=YEARWEEK(NOW(),1) 
                and YEARWEEK(v.dataorainizio,1)>=YEARWEEK(NOW(),1)-10 
                and v.id_campagna=5
              GROUP BY Year, Week )
SELECT `Year`, 
       `Week`, 
       total_price, 
       total_price - LAG(total_price) OVER (ORDER BY `Year`, `Week`) difference
/* or  total_price - LEAD(total_price) OVER (ORDER BY `Year` DESC, `Week` DESC) difference */
FROM cte
ORDER BY Year DESC, Week DESC

скрипка

1 голос
/ 16 марта 2020

Конечно. Вам понадобится подзапрос, например

SELECT YEAR(v.dataorainizio) AS Year, WEEK(v.dataorainizio) AS Week, ROUND(sum(prezzo)/1000,2) as total_price, t2.tp - ROUND(sum(prezzo)/1000,2) 
FROM visita_prodotto vp 
join visita v on vp.id_visita=v.id
join (
    SELECT ROUND(sum(prezzo)/1000,2) as tp
    FROM visita_prodotto vp2 
    join visita v2 on vp2.id_visita=v2.id
    where YEARWEEK(v2.dataorainizio,1)<=YEARWEEK(NOW(),1) and  YEARWEEK(v2.dataorainizio,1)>=YEARWEEK(NOW(),1)-10 and v2.id_campagna=5
    GROUP BY YEAR(v2.dataorainizio), WEEK(v2.dataorainizio)
    HAVING (YEAR(v.dataorainizio) > YEAR(v2.dataorainizio)) OR ((YEAR(v.dataorainizio) = YEAR(v2.dataorainizio)) AND (WEEK(v.dataorainizio) > WEEK(v2.dataorainizio)))
    ORDER BY YEAR(v2.dataorainizio) desc, WEEK(v2.dataorainizio) desc
    LIMIT 0, 1
) t2
where YEARWEEK(v.dataorainizio,1)<=YEARWEEK(NOW(),1) and  YEARWEEK(v.dataorainizio,1)>=YEARWEEK(NOW(),1)-10 and v.id_campagna=5
GROUP BY Year, Week, t2.tp
order by Week desc

Подзапрос выбирает одну группу, находящуюся раньше, чем текущая группа, а затем выполняет вычитание. У меня нет примера базы данных. Если вы все еще боретесь, то создайте SQL Fiddle и поделитесь ссылкой здесь в разделе комментариев.

0 голосов
/ 16 марта 2020

Только для версий MySQL старше вашей ...

SELECT n.yw
     , n.total
     , ROUND(n.delta,2) delta 
  FROM  
     ( SELECT a.* 
            , @prev := total-@prev delta
            , @prev := total 
         FROM 
            ( SELECT DATE_FORMAT(dataorainizio,'%Y-%u') yw
                   , SUM(prezzo)/1000 total 
                FROM visita v 
                JOIN visita_prodotto vp 
                  ON vp.id_visita = v.id 
               GROUP 
                  BY yw
            ) a
            , (SELECT @prev:=null) vars ORDER BY yw
     ) n 
 ORDER 
    BY yw DESC;
+---------+----------+---------+
| yw      | total    | delta   |
+---------+----------+---------+
| 2020-11 | 237.4980 |  233.00 |
| 2020-09 |   4.5000 | -130.18 |
| 2020-08 | 134.6760 |  114.68 |
| 2020-07 |  20.0000 |    NULL |
+---------+----------+---------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...