Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MySQL > вычислить разницу во времяни


Автор: Areostar 5.1.2021, 23:00
Имеется примерно такая схема
Код

CREATE TABLE `transactions` (
  `record_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `trasaction_time` timestamp NOT NULL DEFAULT current_timestamp(),
  `status` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `transactions`
--

INSERT INTO `transactions` (`record_id`, `user_id`, `trasaction_time`, `status`) VALUES
(1, 1, '2021-01-01 06:33:17', 1),
(2, 1, '2021-01-01 18:03:17', 2),
(3, 2, '2021-01-01 06:04:32', 1),
(4, 2, '2021-01-01 18:04:10', 2),
(5, 1, '2021-01-02 06:28:20', 1),
(6, 1, '2021-01-02 17:58:29', 2),
(7, 2, '2021-01-02 06:40:42', 1),
(8, 2, '2021-01-02 18:40:42', 2),
(9, 1, '2021-01-03 06:02:11', 1),
(10, 1, '2021-01-03 18:41:12', 2),
(11, 2, '2021-01-03 05:55:33', 1),
(12, 2, '2021-01-03 17:45:33', 2);

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `login` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
  `first_name` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
  `status` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `login`, `first_name`, `status`) VALUES
(1, 'algol', 'robert', 1),
(2, 'Atom', 'Tormast', 1);


как мне спомощью только SQL получить примерно такой результат:

Имя юзера дата(день) и продолжительность паюочего дня(транзакция со статусом 1 это начало раюоты со статусом 2 конец)

Заранее спасибо за ответ

Автор: ksnk 6.1.2021, 02:21
Что-то типа такого (для Mysql)
Код

select  u.first_name, 
TIMEDIFF(x.trasaction_time,x.t2) as worktime,
date(x.t2) as `date`
from (
select t.user_id, t.trasaction_time,
(select max(trasaction_time) from transactions 
 where status=1 and user_id=t.user_id and trasaction_time<t.trasaction_time) as t2
from transactions t 
where t.status=2
) x
left join users u on u.id=x.user_id
order by x.trasaction_time;

Сама схема хранения раздельного времени начала и конца рабочего дня крайне неэффективна, приходится делать внутренний подзапрос, чтобы найти минимальное начало рабочего дня для каждого окончания. Нужно обязательно переделать, чтобы окончание рабочего дня хранилось в той же строке таблицы, иначе при большом количестве записей расходы на время выполнения будут расти очень быстро

https://www.db-fiddle.com/f/nP9rPDKFSgnT8UDNw3V9sP/0

Автор: Areostar 9.1.2021, 19:26
Спасибо

Автор: Akina 10.1.2021, 12:02
Цитата(ksnk @  6.1.2021,  03:21 Найти цитируемый пост)
Нужно ..., чтобы окончание рабочего дня хранилось в той же строке таблицы

Скорее всего, не выйдет - дамп сильно похож на данные из контроллера, который иного формата не знает в принципе. К тому же никто не застрахован от ошибок в исходных данных, в т.ч. плановых.

Автор: Areostar 14.1.2021, 09:48
Спасибо. уже разобрался!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)