powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Посоветуйте варианты
9 сообщений из 9, страница 1 из 1
Посоветуйте варианты
    #39938722
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MySQL v8.0.13.0.
Задача - выбрать долг ( d.debt ) всех контрагентов ( c.id ) в месяц ( d.period , задается 1-м числом месяца года).
Решается так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE TABLE `contragents` (
  `id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `data` (
  `id_contragent` int(11) NOT NULL,
  `period` date,
  `debt` double,
  KEY `fk_contr` (`id_contragent`),
  CONSTRAINT `fk_contr` FOREIGN KEY (`id_contragent`) REFERENCES `contragents` (`id`)
);

SELECT c.id, d.debt
FROM data d
RIGHT JOIN contragents c ON d.id_contragent=c.id AND d.period='2018-05-01'


Теперь требуется получить то же самое, но только не за один месяц, а за некоторый период "от" и "до", также задаваемый 1-м числом месяца года, с шагом 1 месяц. К примеру, для "от"='2018-10-01' и "до"='2019-02-01' d.period в запросе должно принимать значения: '2018-10-01', '2018-11-01', '2018-12-01', '2019-01-01', '2019-02-01'. Соответственно, запрос должен вернуть id контрагента и для него 5 значений debt из разного d.period .
Какие есть варианты решения задачи, кроме последовательного многократного выполнения запроса с изменяемым параметром, передаваемым в d.period ? Если они есть, конечно...
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39938782
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну тебе ж рекурсивные CTE доступны...
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39938815
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Ну, доступны-то они доступны... но пока они выше моего понимания :)
Написал я так:
Код: sql
1.
2.
3.
4.
5.
6.
WITH RECURSIVE cte AS (
	SELECT c.id, d.debt, period
	FROM data d
	RIGHT JOIN contragents c ON d.id_contragent=c.id AND d.period>='2018-10-01' AND d.period<='2019-02-01'
)
SELECT * FROM cte


Выдает:
iddebtperiod102018-10-01102018-11-01102018-12-01102019-01-01102019-02-01202018-10-01202018-11-01202018-12-01202019-01-01202019-02-01302018-10-01302018-11-01302018-12-01302019-01-01302019-02-01402018-10-0141158.682018-11-014823.292018-12-0141385.392019-01-0142535.212019-02-01.........26220NULLNULL26345NULLNULL26352NULLNULL26365NULLNULL26378NULLNULL
И вроде поначалу есть по 5 значений debt для одного контрагента (пусть и не столбиком рядом, а последовательно), но к концу полученного результата id идут уже в совсем непонятном порядке. Да и последним id должен быть = 26448.
Помогите, пожалуйста, скорректировать запрос так, чтобы на выходе было примерно следующее:
iddebt_2018-10-01debt_2018-11-01debt_2018-12-01debt_2019-01-01debt_2019-02-01100000..................26448NULLNULLNULLNULLNULL
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39938822
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing
чтобы на выходе было примерно следующее
Это уже вообще pivot, который в MySQL не поддерживается. Тут только хранимкой (а лучше - формировать сводную на клиенте).
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39938954
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LiYing,
pivot на мускуле реализуется через SUM.
Не ваш случай, но в качестве примера подойдет, думаю
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SELECT CONCAT(u.last_name, ' ', u.first_name) agent_fullname,
       SUM(h.moon = 1) '01',
       SUM(h.moon = 2) '02',
       SUM(h.moon = 3) '03',
       SUM(h.moon = 4) '04',
       SUM(h.moon = 5) '05',
       SUM(h.moon = 6) '06',
       SUM(h.moon = 7) '07',
       SUM(h.moon = 8) '08',
       SUM(h.moon = 9) '09',
       SUM(h.moon = 10) '10',
       SUM(h.moon = 11) '11',
       SUM(h.moon = 12) '12',
       COUNT(*) total
FROM users u
JOIN (SELECT create_by, MAX(MONTH(create_time)) moon
      FROM ticket_history
      WHERE YEAR(create_time) = 2020                /* Указать год */
      GROUP BY create_by, ticket_id
     ) h ON h.create_by = u.id
GROUP BY u.id
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39938961
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paver
pivot на мускуле реализуется через SUM

PIVOT средствами MySQL
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39938979
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Ваша процедура и тест работают хорошо. Однако, я все равно не понимаю, как мне выбрать данные в моем случае, чтобы передать их на вход pivot. Any help?
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39938984
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing
как мне выбрать данные в моем случае
Ну вариантов два. Либо корректировать процедуру, чтобы она выбирала только нужные записи, либо в начале вместо исходной таблицы создать представление, выбирающее только нужные записи, и его уже пивотить.
...
Рейтинг: 0 / 0
Посоветуйте варианты
    #39940137
НАТАЛИ353
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДОБРЫЙ ДЕНЬ!


ЕСТЬ 2 ЗАПРОСА. кАК МНЕ ВЫЧЕСТЬ РЕЗУЛЬТАТ ОДНОГО ЗАПРОСА ОТ РЕЗУЛЬТАТА ДРУГОГО ЗАПРОСА:



1 ЗАПРОС:
select s.operator,avg(s.billsec) from
(select s.operator,s.billsec, @rownum11:=@rownum11+1 as row_number, @total_rows:=@rownum11
from cc_sessions s, (select @rownum11=0) r
where s.billsec > 20
and s.op_answer_time between '2020-03-17 00:00:00' and '2020-03-18 23:59:59'
and s.operator='5655'
order by billsec asc) s
where s.row_number in (floor((@total_rows+1)/2),floor((@total_rows+2)/2))

2 ЗАПРОС:
select t.operator, sum(t.billsec)/2 from
(
SELECT k.row_number,k.operator,k.op_answer_time, k.billsec from
(
SELECT COUNT(billsec)*0.25 as quart from (select @rownum18:=@rownum18+1 as row_number, operator,op_answer_time, billsec
from cc_sessions
where operator='5655'
AND
op_answer_time between '2020-03-17 00:00:00' and '2020-03-18 23:59:59'
AND
billsec >20
order by billsec) r)r,
(select @rownum19:=@rownum19+1 as row_number, operator,op_answer_time, billsec
from cc_sessions
where operator='5655'
AND
op_answer_time between '2020-03-17 00:00:00' and '2020-03-18 23:59:59'
AND
billsec >20
order by billsec) k
where k.row_number in (floor(r.quart),ceil(r.quart))
)t
group by t.operator
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Посоветуйте варианты
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]