Data step merge has a similar functionality of an outer join, but the result depends on the data. If your relationship between the table keys are 1-M, you will see the same result. In your example, there is a M-M relationship.
This is due to the fact that SQL is acting on columns, and the data step has a more row oriented approach.
SQL tries to combine all id values between the two tables, and then select the matches (that meet the join criteria). The data step merge by will put the two tables beside each other. As long there is a match in the BY group, the data step will go to the next row in both tables until there is no match. So, if you have two rows with id=1 in table a, and three rows with id=1 in table two, you will end up with three rows in your output table. Row three will be data from row two in table a, and row three in table b.
Hope I could make this any sense...
Regards,
Linus
Data never sleeps