Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Let <code>$shift_id</code> be the id of the shift that your user wants to swap.</p> <pre><code>select swappable.shift_id, swappable.user_id, swappable.description, FROM_UNIXTIME(swappable.shiftstart) as start, FROM_UNIXTIME(swappable.shiftend) as end, (swappable.shiftend - swappable.shiftstart) - sum(coalesce(least(conflict.shiftend, swappable.shiftend) - greatest(conflict.shiftstart, swappable.shiftstart), 0)) as swaptime, group_concat(conflict.shift_id) as conflicts, group_concat(concat(FROM_UNIXTIME(conflict.shiftstart), ' - ', FROM_UNIXTIME(conflict.shiftend))) as conflict_times from shifts as problem join shifts as swappable on swappable.user_id != problem.user_id left join shifts as conflict on conflict.user_id = problem.user_id and conflict.shiftstart &lt; swappable.shiftend and conflict.shiftend &gt; swappable.shiftstart where problem.shift_id = 1 group by swappable.shift_id having swaptime &gt; 0; </code></pre> <p>Tested with:</p> <pre><code>CREATE TABLE `shifts` ( `shift_id` int(10) unsigned NOT NULL auto_increment, `user_id` varchar(20) NOT NULL, `shiftstart` int unsigned NOT NULL, `shiftend` int unsigned NOT NULL, `description` varchar(32) default NULL, PRIMARY KEY (`shift_id`) ); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (1,'april', UNIX_TIMESTAMP('2009-04-04 10:00:00'),UNIX_TIMESTAMP('2009-04-04 12:00:00'),'Needs to be swapped'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (2,'bill', UNIX_TIMESTAMP('2009-04-04 10:30:00'),UNIX_TIMESTAMP('2009-04-04 11:30:00'),'Inside today'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (3,'casey', UNIX_TIMESTAMP('2009-04-04 12:00:00'),UNIX_TIMESTAMP('2009-04-04 14:00:00'),'Immediately after today'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (4,'casey', UNIX_TIMESTAMP('2009-04-04 08:00:00'),UNIX_TIMESTAMP('2009-04-04 10:00:00'),'Immediately before today'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (5,'david', UNIX_TIMESTAMP('2009-04-04 11:00:00'),UNIX_TIMESTAMP('2009-04-04 15:00:00'),'Partly after today'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (6,'april', UNIX_TIMESTAMP('2009-04-05 10:00:00'),UNIX_TIMESTAMP('2009-04-05 12:00:00'),'Tommorow'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (7,'bill', UNIX_TIMESTAMP('2009-04-05 09:00:00'),UNIX_TIMESTAMP('2009-04-05 11:00:00'),'Partly before tomorrow'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (8,'casey', UNIX_TIMESTAMP('2009-04-05 10:00:00'),UNIX_TIMESTAMP('2009-04-05 12:00:00'),'Equals tomorrow'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (9,'david', UNIX_TIMESTAMP('2009-04-05 10:30:00'),UNIX_TIMESTAMP('2009-04-05 11:30:00'),'Inside tomorrow'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (10,'april',UNIX_TIMESTAMP('2009-04-11 10:00:00'),UNIX_TIMESTAMP('2009-04-11 12:00:00'),'Next week'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (11,'april',UNIX_TIMESTAMP('2009-04-11 12:00:00'),UNIX_TIMESTAMP('2009-04-11 14:00:00'),'Second shift'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (12,'bill', UNIX_TIMESTAMP('2009-04-11 11:00:00'),UNIX_TIMESTAMP('2009-04-11 13:00:00'),'Overlaps two'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (13,'casey',UNIX_TIMESTAMP('2009-04-11 17:00:00'),UNIX_TIMESTAMP('2009-04-11 19:00:00'),'No conflict'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (14,'april',UNIX_TIMESTAMP('2009-05-04 10:00:00'),UNIX_TIMESTAMP('2009-05-04 12:00:00'),'Next month'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (15,'april',UNIX_TIMESTAMP('2009-05-04 13:00:00'),UNIX_TIMESTAMP('2009-05-04 15:00:00'),'After break'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (16,'bill', UNIX_TIMESTAMP('2009-05-04 11:00:00'),UNIX_TIMESTAMP('2009-05-04 14:00:00'),'Middle okay'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (17,'april',UNIX_TIMESTAMP('2010-04-04 10:00:00'),UNIX_TIMESTAMP('2010-04-04 11:00:00'),'Next year'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (18,'april',UNIX_TIMESTAMP('2010-04-04 11:30:00'),UNIX_TIMESTAMP('2010-04-04 12:00:00'),'After break'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (19,'april',UNIX_TIMESTAMP('2010-04-04 12:30:00'),UNIX_TIMESTAMP('2010-04-04 13:30:00'),'Third part'); insert into `shifts`(`shift_id`,`user_id`,`shiftstart`,`shiftend`,`description`) values (20,'bill', UNIX_TIMESTAMP('2010-04-04 10:30:00'),UNIX_TIMESTAMP('2010-04-04 13:00:00'),'Two parts okay'); </code></pre> <p>Results:</p> <pre><code>'shift_id', 'user_id', 'description', 'start', 'end', 'swaptime', 'conflicts', 'conflict_times' '3', 'casey', 'Immediately after today', '2009-04-04 12:00:00', '2009-04-04 14:00:00', '7200', NULL, NULL '4', 'casey', 'Immediately before today', '2009-04-04 08:00:00', '2009-04-04 10:00:00', '7200', NULL, NULL '5', 'david', 'Partly after today', '2009-04-04 11:00:00', '2009-04-04 15:00:00', '10800', '1', '2009-04-04 10:00:00 - 2009-04-04 12:00:00' '7', 'bill', 'Partly before tomorrow', '2009-04-05 09:00:00', '2009-04-05 11:00:00', '3600', '6', '2009-04-05 10:00:00 - 2009-04-05 12:00:00' '13', 'casey', 'No conflict', '2009-04-11 17:00:00', '2009-04-11 19:00:00', '7200', NULL, NULL '16', 'bill', 'Middle okay', '2009-05-04 11:00:00', '2009-05-04 14:00:00', '3600', '15,14', '2009-05-04 13:00:00 - 2009-05-04 15:00:00,2009-05-04 10:00:00 - 2009-05-04 12:00:00' '20', 'bill', 'Two parts okay', '2010-04-04 10:30:00', '2010-04-04 13:00:00', '3600', '19,18,17', '2010-04-04 12:30:00 - 2010-04-04 13:30:00,2010-04-04 11:30:00 - 2010-04-04 12:00:00,2010-04-04 10:00:00 - 2010-04-04 11:00:00' </code></pre> <p>This shows all shifts for which any portion(s) can be swapped, including how much total time (in seconds) is swappable. The final column, <code>conflict_times</code>, shows the times for which the swapping user is already scheduled to work. It should be easy for the application to extract the available times from that; it's possible, but very tricky, in MySQL.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload