what's being aggregated if the data in the table have not been scanned yet?
Most operators don't process all data at once; they are called repeatedly with the request to return a row. Leaving out the "initialize yourself" calls and focusing on the "give me a row" calls, here is the sequence of operators calling each other for this specific plan.
1. Stream Aggregate is called with a "give me a row" request.
2. Stream Aggregate doesn't have any data yet, so it calls the Nested Loops operator to get a row.
3. Nested Loops has no data yet on either input, so it calls the Table Scan operator to get a row.
4. Table Scan reads first row and returns is to Nested Loops.
5. Nested Loops now calls Index Seek to get a row for its second input.
6. Index Seek reads first index row and returns it to Nested Loops.
7. Nested Loops combines inputs and returns row to Stream Aggregate.
8. Stream Aggregate increases internal results (row counter), then calls Nested Loops again for the next row.
9. Steps 5-8 are repeated until the Index Seek returns a "no more matching rows" condition.
10. Steps 3-9 are repeated until the Table Scan returns a "no more matching rows" condition.
11. At this point, Nested Loops returns "no more matching rows" to its caller.
12. Stream Aggregate receives "no more matching rows" and returns the internal results (row counter) to the caller.
If there had been a GROUP BY, this all would have been a bit more complex - in that case, Stream Aggregate would return a row and reset its internal counter after each change in the GROUP BY values.
So the first operator to execute is the Stream Aggregate (step 1), but the first operator to actually touch any real data is the Table Scan (step 4).