Part 8 — The human requirements › Chapter 48

Analysis, autonomy and teamwork

How to turn “the report is wrong” into a specification, and how to ask for help without looking lost.

From the advert

“Eccellenti capacita di problem solving, proattivita e buon approccio al lavoro in team” — every one of those words is about what you do when nobody has told you what to do. Which is most of the job.

“The report is wrong”

🧒 Simple

Somebody says the number is wrong. They do not know why, and they are not going to find out — that is your part. But they do know what the right number is, and that is the most valuable thing anyone will give you all week. Ask for it first.

🎓 The five questions that turn a complaint into a specification
  1. “What number did you expect, and where did you get it from?” Now you have two figures and a source to reconcile against, instead of a feeling.
  2. “Show me one row that is wrong.” One concrete example collapses the search space faster than any amount of reasoning about the query.
  3. “When was it last right?” Turns an open problem into a change to find.
  4. “Is it wrong for everyone, or just this filter?” Separates a data problem from a query problem.
  5. “What decision does this number drive?” Tells you the tolerance. A figure steering a €400k purchase deserves a different answer from a curiosity.
✔ And then reconcile, do not stare

The technique is always the same: get both numbers in one query and find where they diverge. Not by reading the SQL and hoping — by bisecting. Total by month; the month that differs; total by customer within it; the customer that differs; then the rows. Five queries, and you land on the exact row rather than a theory about it. That is the method, and it works when the query is somebody else's and 300 lines long.

Bisection as a query: find exactly where two sources disagree, then repeat one level down.
-- Where exactly do the two sources disagree?
SELECT month,                                   -- the shared grain
       a.total AS report_says,                  -- what one side thinks…
       b.total AS source_says,                  -- …what the other thinks…
       a.total - b.total AS diff                -- …and by how much
FROM report_monthly a                            -- one side of the comparison
FULL OUTER JOIN source_monthly b USING (month)  -- FULL: keep months missing from EITHER side
WHERE a.total IS DISTINCT FROM b.total          -- null-safe inequality; see chapter 09
ORDER BY ABS(a.total - b.total) DESC;           -- biggest discrepancy first
-- Then repeat one level down, inside the worst month. Five queries, not five hours.
Why each choice here matters
  • FULL OUTER JOIN and not JOIN: a month present in one source and missing from the other is the most interesting case, and an inner join hides exactly that.
  • IS DISTINCT FROM and not <>: with a missing month one side is NULL, and NULL <> 4200 is UNKNOWN, so WHERE would discard the row. The null-safe operator keeps it.
  • USING (month) merges the two month columns into one, so the result has a single month column even where one side contributed nothing.
  • Sorting by ABS(diff) puts the largest discrepancy first, in either direction — which is where to start, because a single large difference usually has a single cause.

Asking for help without looking lost

⚠ The two failure modes, and both are real

Too early: asking before trying looks like you have not engaged, and it trains people to expect it. Too late: three days silently stuck is far worse — it costs the team the time and the trust, because the manager now discovers both the problem and the delay at once. The window is roughly twenty to forty minutes of genuinely no progress.

✔ The four-line ask
The four-line ask: how to be interrupted once instead of three times.
1. What I am trying to do:  make the stock reconciliation match the ledger.
2. What I have tried:       compared by month (matches) and by warehouse
                            (WH-03 is out by 412 units, consistently, since March).
3. Where I am stuck:        I cannot find a movement type that would explain a
                            one-directional difference.
4. What I am asking:        is there a transfer type that bypasses the movements
                            table? Ten minutes of your time, or a pointer.
Why this gets answered and “can I ask you something?” does not
  • Line 2 is the one that earns the answer. It proves you did the work and, incidentally, tells the expert which hypotheses are already eliminated — often enough for them to answer immediately.
  • Line 3 is specific enough to be wrong. “I am stuck” cannot be corrected; “I cannot find a movement type that explains a one-directional difference” can.
  • Line 4 bounds the request. Asking for ten minutes or a pointer is much easier to say yes to than an open-ended “help”.
  • Writing it also solves the problem about a third of the time before you send it, which is the cheapest possible outcome.

This is worth more than the answer. It shows you engaged, it lets them help in one minute instead of twenty, and it makes you the person people are willing to be interrupted by — which is a real professional asset.

What “proattività” actually means here

🎓 Not “do more work”. Notice and report.

Italian adverts ask for proattività constantly and nobody defines it. In practice it means three specific behaviours:

  1. Say when something is wrong before you are asked. “While fixing 412 I noticed the same fan-out in the invoice report — it is probably also over-counting. Shall I raise a ticket?” Noticing and reporting, not silently fixing.
  2. Bring the option, not just the problem. “This will be slow at ten million rows. We could index it now, or accept it and revisit in six months — I would do the index, it is twenty minutes.”
  3. Close the loop. Tell the person who reported it that it is fixed, and what it was. Almost nobody does this, and everybody notices.
⚠ Autonomy is not going quiet for a week

A junior who disappears for five days and returns with a large refactor nobody asked for has not demonstrated autonomy — they have demonstrated risk. Autonomy is making the small decisions yourself and surfacing the ones that are not yours. Adding an index: yours. Changing a column type: not yours. Deciding which of two duplicate customers survives: definitely not yours.

Disagreeing, and being right, without cost

✔ The structure

Agree with the goal. Name the specific risk. Offer the alternative. Accept the decision. — “I agree we need this out on Thursday. My worry is that the migration locks the orders table, and on the largest customer that could be several minutes at 09:00. We could run it at 21:00, or do it in batches so it never holds a long lock. If Thursday morning is fixed, I will do the batched version — it takes a day longer to write.”

And when you are overruled

Say it once, clearly, put it in writing in the ticket, and then execute properly. Continuing to argue after a decision is what gets people labelled difficult — and the written note means that if it goes wrong you are the person who flagged it, without ever having to say “I told you so” out loud.

Talking to people who do not write SQL

Do not saySay
“The query does a table scan”“It reads every order to answer, instead of jumping to the ones you asked for”
“There's a fan-out in the join”“Orders with several payments are being counted once per payment”
“It's a cardinality estimate problem”“The database expected a few hundred rows and got half a million, so it chose a slow strategy”
“We need to denormalise”“We can calculate this overnight instead of each time — the report opens instantly and is up to this morning”
✔ Lead with the consequence

A non-technical stakeholder needs three things and in this order: what it means for them, what you are going to do, when. The mechanism is optional and goes last. Getting that order right is most of what people mean by “good communication skills”, and it is entirely learnable.

  1. “What number did you expect, and where from?” is the first question, always.
  2. One concrete wrong row collapses the search faster than any reasoning about the query.
  3. “When was it last right?” turns an open problem into a change to find.
  4. Reconcile by bisection — month, then customer, then row. Five queries, not five hours.
  5. Ask for help after twenty to forty minutes of no progress, not three days.
  6. Ask in four lines: goal, tried, stuck, request.
  7. Proattività means noticing and reporting, bringing an option, and closing the loop.
  8. Autonomy is making small decisions and surfacing the ones that are not yours.
  9. Disagree once, in writing, then execute the decision properly.
  10. To a stakeholder: consequence, action, timing. Mechanism last, if at all.

Interview questions this chapter answers

A user says a report is wrong. What do you do?

Ask what number they expected and where they got it, and ask for one specific row that is wrong — those two answers turn a complaint into something testable. Then find when it was last right, and reconcile by bisection: totals by month, then within the worst month by customer, then the rows. That lands on the cause in five queries even when the report is somebody else's and three hundred lines long.

Tell me about a time you disagreed with a decision.

Structure it: what the goal was, what specific risk you saw, what alternative you offered, what was decided, and what you did next. The last part is the one being assessed — the good answer ends with executing the decision properly and noting the concern in writing, not with being proved right.

How long do you spend stuck before asking for help?

Twenty to forty minutes of genuinely no progress. And I ask in a structured way — what I am trying to do, what I have already tried and ruled out, where exactly I am stuck, and what I am asking for — so it costs the other person a minute rather than twenty.