GO è come la fine di un copione.
Potresti avere più istruzioni CREATE TABLE, separate da GO. È un modo per isolare una parte dello script da un'altra, ma inviarlo tutto in un blocco.
BEGIN e END sono proprio come { e } in C/++/#, Java, ecc.
Hanno legato un blocco logico di codice. Tendo a usare BEGIN e END all'inizio e alla fine di una procedura memorizzata, ma non è strettamente necessario lì. Dove è necessario sono i cicli for e le istruzioni IF, ecc., dove è necessario più di un passaggio...
IF EXISTS (SELECT * FROM my_table WHERE id = @id)
BEGIN
INSERT INTO Log SELECT @id, 'deleted'
DELETE my_table WHERE id = @id
END