/* a extend b */

select A, B,
case
	when a < b 
		then a
		else b
end
as Start_extend,
case
	when a < b 
		then dateadd(second,1,b)
		else dateadd(second,1,a)
end
as End_extend
from dates


/* p extend q */
select P1,P2,Q1,Q2,
case
	when P1 < Q1
		then P1
		else Q1	 
end
as Start_extend,
case
	when P2 < Q2
		then Q2
		else P2	 
end
as End_extend
from dates


/* p extend a */
select P1,P2,A,
case
	when P1 < A
		then P1
		else A	 
end
as Start_extend,
case
	when P2 < A
		then dateadd(second,1,A)
		else P2	 
end
as End_extend
from dates

/* a extend p */
select P1,P2,A,
case
	when P1 < A
		then P1
		else A	 
end
as Start_extend,
case
	when P2 < A
		then dateadd(second,1,A)
		else P2	 
end
as End_extend
from dates


/* p intersect q */
select P1,P2,Q1,Q2,
case
	when P2 <= Q1 or Q2 <= P1 then NULL
	else 	case
			when P1 < Q1
			then Q1
			else P1	 
		end
end
as Start_intersect,
case
	when P2 <= Q1 or Q2 <= P1 then NULL
	else 	case
			when P2 < Q2
			then P2
			else Q2	 
		end
end
as End_intersect	
from dates


/* p - q */
select P1,P2,Q1,Q2,
case
	when Q1 <= P1 then NULL
	else 	case
			when P1 < Q1 and Q2 < P2 then NULL
			else 	P1
		end
end
as Start_difference,
case
	when Q1 <= P1 then NULL
	else 	case
			when P1 < Q1 and Q2 < P2 then NULL
			else 	case
					when Q1 < P2
					then Q1
					else P2	 
				end
		end
end
as End_difference	
from dates

/* p union q */
select P1,P2,Q1,Q2,
case
	when P2 <= Q1 or Q2 <= P1 then NULL
	else 	case
			when P1 < Q1
			then P1
			else Q1	 
		end
end
as Start_union,
case
	when P2 <= Q1 or Q2 <= P1 then NULL
	else 	case
			when P2 < Q2
			then Q2
			else P2	 
		end
end
as End_union	
from dates
