First, note that your expression only makes sense if mergeData x y has the same type as x and y each have, i.e. if its type is
mergeData :: X -> X -> X
for some concrete type X.
Given that, we can rely on Maybe's Applicative and Alternative instances:
mergeTwoMaybeDatas :: Maybe X -> Maybe X -> Maybe X
mergeTwoMaybeDatas a b = liftA2 mergeData a b <|> a <|> b
If you want to reuse this pattern many times but for different functions, and you think this is not clear, you could define a function parameterizing over mergeData.
But wait, maybe we can do something even simpler! If your mergeData function is associative (i.e., mergeData x (mergeData y z) = mergeData (mergeData x y) z), then your X type is a Semigroup, with mergeData as its combine operation. In that case, consider defining the Semigroup instance. Then you could use the tools designed for Semigroups to handle this even more simply.
data X = ...
instance Semigroup X where
(<>) = mergeData
mergeTwoMaybeDatas :: Maybe X -> Maybe X -> Maybe X
mergeTwoMaybeDatas = (<>)
Amazing: if you give X its Semigroup instance, you don't even have to implement mergeTwoMaybeDatas at all - it's just how (<>) already behaves for a Semigroup lifted into Maybe.
I encourage giving your types instances of all the typeclasses they can reasonably support: you will find many generic tools like this then work on them "for free". Having a Semigroup instance will likely help out for some of your other uses of this X type as well.