Как суммировать строки с одинаковой датой из производной таблицы в Mysql8.0? и почему GROUP BY не удалось? - PullRequest
0 голосов
/ 21 марта 2020

Это код. Проблема в том, что результат имеет дубликат даты. Я хочу суммировать количество повторяющихся дат каждого столбца по GROUP BY, но там написано, что «это несовместимо с sql_mode = only_full_group_by»,

Кто-то предлагает отключить этот параметр. Я не знаю как и удивляюсь, как лучше решить эту проблему.

Схема (MySQL v8.0)

CREATE TABLE IF NOT EXISTS `test` (
  `Date` DATE NOT NULL,
  `USD` VARCHAR(10) NOT NULL,
  `EUR` VARCHAR(10) NOT NULL
) DEFAULT CHARSET=utf8;

INSERT INTO `test` VALUES
  ('2020-03-06', -1000000,6930860),
  ('2020-03-07', -1000000,6930860),
  ('2020-04-13', -2000000,13966090),
  ('2020-05-13', -2000000,13963260),
  ('2020-05-28',  1000000,-654773.8),
  ('2020-06-01',  1000000,-1135530);

CREATE TABLE IF NOT EXISTS `test2` (
  `Date` DATE NOT NULL,
  `USD` VARCHAR(10) NOT NULL,
  `EUR` VARCHAR(10) NOT NULL
) DEFAULT CHARSET=utf8;

INSERT INTO `test2` VALUES
  ('2020-03-05', -1000011,6930860),
  ('2020-03-09', -1000022,6930860),
  ('2020-04-3', -2000033,13966090),
  ('2020-05-10', -2000044,13963260),
  ('2020-05-28',  1000055,-654773.8),
  ('2020-06-01',  1000066,-1135530);

Запрос # 1

SELECT * FROM
  ((SELECT * FROM
      (SELECT Date FROM test
      UNION
      SELECT Date FROM test2
      ORDER BY Date) AS d
  LEFT OUTER JOIN test USING (Date))
  UNION
  (SELECT * FROM
      (SELECT Date FROM test
      UNION
      SELECT Date FROM test2
      ORDER BY Date) AS d2
  LEFT OUTER JOIN test2 USING (Date))) AS D
ORDER BY Date ASC;
| Date       | USD      | EUR       |
| ---------- | -------- | --------- |
| 2020-03-05 | -1000011 | 6930860   |
| 2020-03-05 |          |           |
| 2020-03-06 | -1000000 | 6930860   |
| 2020-03-06 |          |           |
| 2020-03-07 | -1000000 | 6930860   |
| 2020-03-07 |          |           |
| 2020-03-09 | -1000022 | 6930860   |
| 2020-03-09 |          |           |
| 2020-04-03 | -2000033 | 13966090  |
| 2020-04-03 |          |           |
| 2020-04-13 | -2000000 | 13966090  |
| 2020-04-13 |          |           |
| 2020-05-10 |          |           |
| 2020-05-10 | -2000044 | 13963260  |
| 2020-05-13 | -2000000 | 13963260  |
| 2020-05-13 |          |           |
| 2020-05-28 | 1000000  | -654773.8 |
| 2020-05-28 | 1000055  | -654773.8 |
| 2020-06-01 | 1000000  | -1135530  |
| 2020-06-01 | 1000066  | -1135530  |

Мне нужен такой результат.
1. Одна дата в одной строке и
2. СУММА суммы на ту же дату.
3. удалить пустые строки.

enter image description here

Спасибо.

Посмотреть на БД Fiddle

Ответы [ 3 ]

2 голосов
/ 21 марта 2020

Все, что вам нужно, это UNION ALL для 2 таблиц и агрегации:

select t.Date, sum(t.USD) USD, sum(t.EUR) EUR
from (
  select * from test
  union all
  select * from test2
) t 
group by t.Date
order by t.Date

См. Демоверсию . Результаты:

| Date       | USD      | EUR        |
| ---------- | -------- | ---------- |
| 2020-03-05 | -1000011 | 6930860    |
| 2020-03-06 | -1000000 | 6930860    |
| 2020-03-07 | -1000000 | 6930860    |
| 2020-03-09 | -1000022 | 6930860    |
| 2020-04-03 | -2000033 | 13966090   |
| 2020-04-13 | -2000000 | 13966090   |
| 2020-05-10 | -2000044 | 13963260   |
| 2020-05-13 | -2000000 | 13963260   |
| 2020-05-28 | 2000055  | -1309547.6 |
| 2020-06-01 | 2000066  | -2271060   |

Примечание: хотя MySql очень гибок в отношении неявных преобразований типов данных, вы не должны использовать тип данных VARCHAR для числовых значений c. Вместо этого используйте для этого случая DECIMAL(13,2)

2 голосов
/ 21 марта 2020

Пожалуйста, используйте следующий запрос. Я надеюсь, что это будет работать, как вы ожидали.

PS. Пожалуйста, не используйте "ЗАКАЗАТЬ ПО ДАТЕ" в своем подзапросе. Это замедлит ваш запрос.

SELECT Date FROM test2
      ORDER BY Date
SELECT 
    `DATE`,
    SUM(USD) AS USD,
    SUM(EUR) AS EUR 
FROM
    (
        (SELECT 
            * 
        FROM
            (SELECT 
                DATE 
            FROM
                test 
            UNION
            SELECT 
                DATE 
            FROM
                test2) AS d 
            LEFT OUTER JOIN test USING (DATE)) 
        UNION
        (SELECT 
            * 
        FROM
            (SELECT 
                DATE 
            FROM
                test 
            UNION
            SELECT 
                DATE 
            FROM
                test2) AS d2 
            LEFT OUTER JOIN test2 USING (DATE))
    ) AS D 
GROUP BY `DATE` ;
1 голос
/ 21 марта 2020
WITH 
dates AS ( SELECT test.Date FROM test 
           UNION
           SELECT test2.Date FROM test2 ),
total AS ( SELECT *
           FROM dates
           LEFT JOIN test USING(Date) 
           UNION ALL
           SELECT *
           FROM dates
           LEFT JOIN test2 USING(Date) )
SELECT total.Date, SUM(USD) USD, SUM(EUR) EUR
FROM total
GROUP BY total.Date
ORDER BY total.Date;

или

WITH 
dates AS ( SELECT test.Date FROM test 
           UNION
           SELECT test2.Date FROM test2 ),
total AS ( SELECT *
           FROM test
           UNION ALL
           SELECT *
           FROM test2 )
SELECT dates.Date, SUM(total.USD) USD, SUM(total.EUR) EUR
FROM dates
JOIN total USING (Date)
GROUP BY dates.Date
ORDER BY dates.Date;

или

WITH 
total AS ( SELECT *
           FROM test
           UNION ALL
           SELECT *
           FROM test2 ),
dates AS ( SELECT DISTINCT total.Date 
           FROM total )
SELECT dates.Date, SUM(total.USD) USD, SUM(total.EUR) EUR
FROM dates
JOIN total USING (Date)
GROUP BY dates.Date
ORDER BY dates.Date;

скрипка

И много других вариантов ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...