ThisWhile valid, it's unlikely this will never run successfully -- even for a single job. The data views are just not that performant, unfortunately.
I'd suggest one query for every activity type.
The first one based on _Sent
that does an overwrite and the subsequent three are updates and based on the rows resulting from the first query.
You should also join on SubscriberID as @Chris suggested.
If you don't want to do that, I'd suggest mirroring the data views in your own set of Data Extensions and refreshing them daily. That way you can control the primary keys.
These work-arounds are a ton of unnecessary work and, frankly, a big pain in the butt. Believe me, I know.