Block Type with the Most Children
Reported by candidates from Notion's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Notion's March 2026 OA has a SQL question with one line that decides everything: root blocks don't count as children. Miss it and your counts are off by a few rows. The task is to find which parent block type has the most direct children across all blocks of that type. It's a self-join plus a GROUP BY, with a tiebreak on the alphabetically smallest type. No fancy algorithm, just careful reading. If you blank on the join direction during the live assessment, StealthCoder is the silent safety net running on your desktop that the proctor can't see.
The problem
Each block can be a root or a direct child of another block. Return the parent block type whose blocks collectively have the largest number of direct children. Do not count root blocks as children. If several parent types tie, return the alphabetically smallest type. Return block_type and child_count. Tables blocks: block_id PK (Integer), parent_block_id (Integer), block_type (Text) Constraints parent_block_id is null only for root blocks. At least one child block is present. Count only direct parent-child relationships.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is a self-join. Join blocks c to blocks p on c.parent_block_id = p.block_id. The inner join drops roots automatically, since their parent_block_id is null and matches nothing. Then group by p.block_type and count c.block_id. That gives child_count per parent type. Sort by child_count descending, then block_type ascending, and take LIMIT 1. The common pitfall is grouping by the child's type instead of the parent's, which answers a different question. Another is counting parents rather than children, or using a LEFT JOIN and counting rows that include null matches. Direct relationships only means one hop, so no recursion is needed. If the join direction trips you up mid-OA, StealthCoder reads the schema on screen and hands you the query as a hedge.
Memorize the pattern. If you can't, run StealthCoder. The proctor sees the IDE. They don't see what's behind it.
You can drill Block Type with the Most Children cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Notion's OA.
Notion reuses patterns across OAs. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Block Type with the Most Children FAQ
How hard is the Notion block type SQL question really?+
Easy to medium. It's one self-join, one GROUP BY, and an ORDER BY with a tiebreak. The difficulty is reading it right: group by the parent's type, count the children, and skip roots. If you've written a self-join before, it's a five-minute problem.
What's the trick to this query?+
Self-join blocks to itself with child.parent_block_id = parent.block_id. Group by parent.block_type and count child rows. The inner join excludes roots for free because null never equals anything. Don't group by the child's type, that's the classic mistake.
How do I handle ties?+
Order by child_count DESC, then block_type ASC, and use LIMIT 1. The second sort key is what returns the alphabetically smallest type on a tie. Forgetting it can give you a random row among tied types, which fails hidden tests.
Do I need a recursive CTE?+
No. The problem says count only direct parent-child relationships, so it's a single hop. A recursive CTE would count grandchildren and inflate your numbers. Keep it to one join.
How do I prepare for this in 48 hours?+
Practice self-joins on an employee-manager style table, then GROUP BY with COUNT and a two-key ORDER BY. Write the query from scratch twice. Also check NULL behavior in joins, since that's what silently removes the root blocks here.