N036-H1 Tier 3 · Intermediate · hard ecommerce · Brightlane

Return two values in a single row: the output of concatenating `'Customer: '` and a SQL `NULL` using the `||` operator, and the output of passing those same values to `CONCAT`

Part of String Concatenation and Formatting in SQL

The problem

Brightlane's engineering team is documenting the difference in missing-input behavior between the || operator and the CONCAT function.

Write a query to return two values in a single row: the output of concatenating 'Customer: ' and a SQL NULL using the || operator, and the output of passing those same values to CONCAT.

Output:

  • A single row with columns pipe_result (the || output, which will be missing) and concat_result (the CONCAT output, which will be the prefix 'Customer: ' alone).
Schema · ecommerce 5 tables
categories
id integer
name text
parent_id? integer
products
id integer
name text
category_id integer
price numeric
stock_qty integer
attributes? jsonb
order_items
id integer
order_id integer
product_id integer
quantity integer
unit_price numeric
customers
id integer
name text
email text
city? text
country text
created_at timestamptz
is_active boolean
orders
id integer
customer_id integer
ordered_at timestamptz
status text
total_amount numeric

Run previews · Check grades

Write a query, then run it to see results here.

Worked solution Try it yourself first
Solution query
SELECT
  'Customer: ' || NULL AS pipe_result,
  CONCAT('Customer: ', NULL) AS concat_result

The shape

The two columns surface the exact behavioral split the engineering team is documenting: || returns NULL when either operand is NULL, and CONCAT returns the present value alone, treating the NULL as an empty string. Running both expressions in one row puts the contrast on a single line of output.

Clause by clause

  • SELECT 'Customer: ' || NULL AS pipe_result evaluates the || concatenation on a known prefix and a NULL right operand. || follows the universal NULL-propagation rule: a NULL anywhere in the expression makes the whole result NULL. The prefix is not preserved; pipe_result comes back as a missing value.
  • , CONCAT('Customer: ', NULL) AS concat_result evaluates the same two values through CONCAT instead. CONCAT walks its argument list and treats each NULL as an empty string, so the prefix is concatenated against nothing and concat_result comes back as the string 'Customer: '. There is no FROM because both expressions are evaluated directly from the literals supplied in the query.

Why this and not running each form in a separate query

The whole point of the documentation row is the side-by-side contrast. A learner reading the result table sees pipe_result = NULL and concat_result = 'Customer: ' on the same line, against the same inputs, and the difference becomes a single mental snapshot. Splitting them across two queries forces the reader to context-switch between two result panels and reconstruct the comparison.

The trap

The contrast looks like a stylistic choice but is a semantics decision the rest of the codebase depends on. If a display label needs to vanish entirely when any input is missing (so a downstream consumer can detect the gap), || is the right tool. If a display label should keep showing whatever pieces are present (so the user still sees something), CONCAT is. Pick the wrong one and the report either silently drops rows or silently shows incomplete labels as if they were complete, with no error path to alert anyone. The choice is not interchangeable on real data.

You practiced contrasting || against CONCAT(...) on a missing input — || propagates the missing value through, CONCAT treats it as an empty string; the choice between them is a NULL-semantics decision.

How you actually get good at SQL

Reading explains SQL. Writing it, over and over with instant feedback, is what makes you fluent.

That's the whole SQLMaxx loop: 600+ real problems, instant AI feedback, mastery you can actually see, and spaced review that won't let you forget.

A stack of SQL practice problem cards, the top card showing an employees table.
615 problems · 66 concepts

Real problems. Not toy examples.

615 hand-built problems spanning all 66 concepts, from basic SELECTs to window functions, built on real schemas and real business questions, the kind you'll actually get asked on the job. Enough reps to make SQL automatic.

A retro computer showing a SQL query marked correct with a green checkmark.
Instant AI feedback

Write a query. Know if it's right in one second.

No copying an answer and hoping it clicked. The AI grader checks your real query against real data, catches exactly what's wrong, and explains the fix in plain English, like a senior analyst reading over your shoulder on every problem.

A circular mastery progress dial filling from blue to green, the SQLMaxx diamond at its center.
Mastery tracking

Stop guessing whether you actually know it.

SQLMaxx tracks every concept and shows you what you've mastered and what's still shaky. Your skills fill in one concept at a time, so 'I think I get joins' becomes something you can prove.

A SQL query editor circled by a blue return arrow with a clock, scheduled to come back for review.
Spaced review

Learn it once. Keep it for good.

Most of what you learn this week fades by next week. So when a concept comes due for review, SQLMaxx hands you a fresh problem to solve from a blank editor, not a flashcard to re-read. A research-backed spaced-repetition algorithm (FSRS) times each return for right before you'd forget, so your SQL is still there months later, when the interview or the job actually needs it.

Practice, feedback, mastery, review. That's the loop that turns reading into real skill.

Start free

No account, no credit card. Start solving in under a minute.