When you put from a register, the content of the register determines how it is put.
If the content of the register ends with an "EOL" character, the put is done "linewise", meaning that it happens on a new line, below or above the current one.
If the content of the register doesn't end with an "EOL" character, the put is done "characterwise", meaning that it happens in the current line, before or after the cursor.
When you do Vy or yy, it is the whole line, including the "EOL", that is yanked, so when you do p, the put is done "linewise" and you get your yanked line below the current line. It makes a lot of sense: you yank a line, you put a line.
If you want to yank the content of a line and thus ensure that it will be put "characterwise", which is relatively less common than what Vim is optimised for, you must omit the "EOL". For this you need to know these four motions:
0 moves the cursor to the first character of the line,
^ moves the cursor to the first non-whitespace character of the line,
$ moves the cursor to the last character of the line,
g_ moves the cursor to the last non-whitespace character of the line,
which you can combine with y to yank exactly what you want from the current line:
0y$ yanks everything from the first character up to and excluding the "EOL",
^y$ yanks everything from the first non-whitespace character up to and excluding the "EOL",
0yg_ yanks everything from the first character up to the last non-whitespace character,
^yg_ yanks everything from the first non-whitespace character up to the last non-whitespace character.
In my opinion, the commands above are intuitive and expressive enough to be used when needed but, if you really want a single character command, then you can simply make a custom mapping:
nnoremap <key> ^yg_
Reference:
:help linewise
:help 0
:help ^
:help $
:help g_