to declare a cte, the next statement must include it, otherwise it's out of scope. You're query has 2 CTEs, so it doesn;t work. You'll need to nest them to get it to work
With data1 as (SELECT * from tablea),
data2 as (SELECT * from tableb)
I don't understand your question - the semi-colon is a statement terminator and although it is not required in all statements, it is required in certain cases. It is a good habit to get into...
The Go is a batch terminator - and is required in a script where you have multiple statements. So if you had a script to build multiple views it would be required.
If you are thinking you can 'define' a view in a stored procedure then use it later - that is not the purpose of views. A view would be used when you have a defined query that is used in multiple other queries (procedures) - or where you want to give a user access to a subset of rows or columns. It is not a technique for creating 'sub-queries' in a procedure.
If you want to define a sub-query in a stored procedure and use it in later code - then you want either a temp table, table variable or common table expression.