Выберите время, сумму и группируйте по столбцам также для не вставленных значений, которые используются в разное время - PullRequest
1 голос
/ 20 октября 2019

Я борюсь с избранным.

У меня три стола.

доход таблица:

-----------------------------------------------------------
|ID_income    |ID_time_period    |ID_type_income    |Value|
-----------------------------------------------------------
|1            |1                 |1                 |150  | 
|2            |1                 |2                 |180  |
|3            |1                 |3                 |10   |
|4            |1                 |1                 |150  |
|5            |2                 |1                 |54   |
|6            |2                 |1                 |30   |
|7            |2                 |4                 |20   |
-----------------------------------------------------------

time_period таблица:

-------------------------------------
|ID_time_period      |Name_of_period|
-------------------------------------
|1                   |1.2018        |
|2                   |2.2018        |
-------------------------------------

type_of_income :

------------------------------
|ID_type_income    |Type     |
------------------------------
|1                 |Tools    |
|2                 |Tax      |
|3                 |Machine  |
|4                 |Fuel     |
|5                 |Other    |
------------------------------

Моя цель - получить таблицу, в которой у меня есть сумма для значений для каждого периода времени и в каждом периоде, а также для всех видов доходов в течение всего периода времени

SELECT 
    time_period.Name_of_period AS period, 
    type_of_income.Type AS Type, 
    SUM(value) AS valuesum 
FROM 
    income 
LEFT JOIN 
    type_of_income ON income.ID_type_income = type_of_income.ID_type_income 
LEFT JOIN 
    time_period ON income.ID_time_period = time_period.ID_time_period 
WHERE 
    time_period.ID_time_period > 0 
    AND time_period.ID_time_period <= 2 
GROUP BY 
    time_period.Name_of_period, Type 
ORDER BY 
    time_period.ID_time_period

Отчет засоздание и вставка данных

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";

CREATE TABLE `income` (
  `ID_income` int(11) NOT NULL,
  `ID_time_period` int(11) NOT NULL,
  `ID_type_income` int(11) NOT NULL,
  `Value` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO `income` (`ID_income`, `ID_time_period`, `ID_type_income`, `Value`) VALUES
(1, 1, 1, 150),
(2, 1, 2, 180),
(3, 1, 3, 10),
(4, 1, 1, 150),
(5, 2, 1, 54),
(6, 2, 1, 30),
(7, 2, 4, 20);

CREATE TABLE `time_period` (
  `ID_time_period` int(11) NOT NULL,
  `Name_of_period` varchar(20) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO `time_period` (`ID_time_period`, `Name_of_period`) VALUES
(1, '1.2018'),
(2, '2.2018');

CREATE TABLE `type_of_income` (
  `ID_type_income` int(11) NOT NULL,
  `Type` varchar(20) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO `type_of_income` (`ID_type_income`, `Type`) VALUES
(1, 'Tools'),
(2, 'Tax'),
(3, 'Machine'),
(4, 'Fuel'),
(5, 'Other');


ALTER TABLE `income`
  ADD PRIMARY KEY (`ID_income`);

ALTER TABLE `time_period`
  ADD PRIMARY KEY (`ID_time_period`);

ALTER TABLE `type_of_income`
  ADD PRIMARY KEY (`ID_type_income`);


ALTER TABLE `income`
  MODIFY `ID_income` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;

ALTER TABLE `time_period`
  MODIFY `ID_time_period` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;

ALTER TABLE `type_of_income`
  MODIFY `ID_type_income` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
COMMIT;

Я получаю таблицу, но не с данными, которых нет. Я получаю

-----------------------------
|period    |Type   |valuesum|
-----------------------------
|1         |1      |300     |
|1         |2      |180     |
|1         |3      |10      |
|2         |1      |84      |
|2         |4      |20      |
-----------------------------

Мне нужен вывод, подобный этому

-----------------------------
|period    |Type   |valuesum|
-----------------------------
|1         |1      |300     |
|1         |2      |180     |
|1         |3      |10      |
|1         |4      |0       |
|2         |1      |84      |
|2         |2      |0       |
|2         |3      |0       |
|2         |4      |20      |
-----------------------------

Вы можете видеть, что type_of_income 5 не упоминается, поскольку он не указан в таблице доходов

Ответы [ 2 ]

0 голосов
/ 20 октября 2019

Как уже упоминалось в вашем посте, type_of_income 5 не упоминается, потому что это не упоминается в таблице доходов .

, поэтому вам нужно принять отличное значение ID_type_income от incomeи выполните cross join с time_period.

Затем выполните left join с income таблицей и в результате вы можете получить сумму value.

Метод # 1
На основе желаемого результата в виде таблицы.

SELECT 
    p.ID_time_period as period,
    t1.ID_type_income as Type,
    COALESCE(SUM(i.Value), 0) AS valuesum
FROM
    time_period p
    CROSS JOIN (SELECT DISTINCT ID_type_income FROM income) AS t1
    LEFT JOIN income i ON p.ID_time_period = i.ID_time_period AND t1.ID_type_income = i.ID_type_income
GROUP BY 
    p.ID_time_period, t1.ID_type_income;

Результат # 1

period | Type | valuesum
-----: | ---: | -------:
     1 |    1 |      300
     1 |    2 |      180
     1 |    3 |       10
     1 |    4 |        0
     2 |    1 |       84
     2 |    2 |        0
     2 |    3 |        0
     2 |    4 |       20

Метод # 2
На основе Name и Type в качестве результата вместо id

SELECT 
    p.Name_of_period AS period,
    toi.Type AS Type,
    COALESCE(SUM(i.Value), 0) AS valuesum
FROM
    time_period AS p
    CROSS JOIN (SELECT DISTINCT ID_type_income AS typ_inc FROM income) AS t1
    JOIN type_of_income AS toi ON t1.typ_inc = toi.ID_type_income
    LEFT JOIN income AS i ON p.ID_time_period = i.ID_time_period AND toi.ID_type_income = i.ID_type_income
GROUP BY 
    p.ID_time_period, toi.ID_type_income;

Результат # 2

period | Type    | valuesum
:----- | :------ | -------:
1.2018 | Tools   |      300
1.2018 | Tax     |      180
1.2018 | Machine |       10
1.2018 | Fuel    |        0
2.2018 | Tools   |       84
2.2018 | Tax     |        0
2.2018 | Machine |        0
2.2018 | Fuel    |       20

См. db-fiddle

0 голосов
/ 20 октября 2019

Полагаю, вам нужно только изменить порядок таблиц -

SELECT time_period.Name_of_period as period, 
type_of_income.Type as Type, 
sum(value) as valuesum 
FROM type_of_income
LEFT JOIN income ON income.ID_type_income=type_of_income.ID_type_income
LEFT JOIN time_period ON income.ID_time_period=kvartaly.ID_time_period
WHERE time_period.ID_time_period>0 and time_period.ID_time_period<=2 
GROUP BY time_period.Name_of_period,Type
ORDER BY time_period.ID_time_period
...