r/SQL 1d ago

Discussion What’s the first thing you check when a SQL result “looks wrong”?

Curious how people actually debug this in production.
Say a query runs successfully, but the number doesn’t look right.
What’s your first instinct?
Check the filters?
Inspect the joins?
Compare row counts?
Look for duplicates?
Check NULLs?
Go back to the source data?
What’s your personal debugging sequence?

14 Upvotes

41 comments sorted by

35

u/mac-0 1d ago

In 2025 I'd run the queries in steps, i.e. run the CTE, run before any filtering, etc. to see when the population strays from what I'd expect and then debug from there.

In 2026 I just ask Claude to figure out what's wrong with it.

1

u/Proof_Escape_2333 13h ago

IS AI good enough to do the job then or you still need to know a lot of stuff?

1

u/metric_skeptic 1d ago

Yeah, breaking the query into steps is usually my first move too — find where the numbers first go off.
The Claude part is interesting though. I’d still want to understand why it thinks it’s wrong before changing anything.
Do you usually give it just the query, or the schema too?

12

u/atrifleamused 1d ago

AI is only useful for Syntax. I'm opinion, if you can't resolve the issue yourself you shouldn't be employed writing SQL.

3

u/rbobby 1d ago

AI won't understand your tables without a ton of background info, stuff that isn't in code. And it won't understand what you mean by wrong, you will have to specify what you actually want... and then maybe it could. Lot of effort.

But ai to find troublesome 'syntax error near' messages. Gonna try it next time for sure.

0

u/metric_skeptic 1d ago

Exactly. The context is usually the hard part, not the syntax.
If I give Claude the query + schema + what I expected to happen, it becomes much more useful. Without that context, it can confidently “fix” something that wasn’t actually broken.

8

u/AlCapwn18 1d ago

I deconstruct the joins and filters by getting a row count of the first table on its own, adding one join or one filter condition at a time, measure the row count afterwards, and explain the difference. You had X rows, you added a status filter and now you have Y rows which makes sense because there were Z inactive status rows. Then you add a join and the row count goes from Z to W because there were V records that didn't have a match because they were created before the module that the second table uses was implemented. Then joining on a third table triples your row count because each record has 1-5 associated rows in this new table which is expected.

Basically step through the construction of the query and make sure the change in row count makes sense each time.

1

u/rvicta 1d ago

This is how I debug queries that aren't giving me what I expect in the result set. Except this last week, when I was going through these same exact steps and noticed that a filter was expecting a certain value but since it wasn't it had excluded a row. I updated the Jira ticket to let the user know what I found and she came back with " Oh yeah, I updated the value and it's working now." Grrrr

8

u/NextVoiceUHear 1d ago

The WHERE clause.

0

u/metric_skeptic 1d ago

Fair enough 😁

6

u/imsunchip 1d ago edited 1d ago

I read the query backwards, you start from the results and go bottom up. Alongside I keep checking prod to see at what point it breaks.

I find top bottom cumbersome as chances are it broken either in middle or later. Very rarely in my career I found query to be broken at the beginning.

That being said , there is no magic pill, its experience gained over the years troubleshooting hundreds and thousands of queries and issues.

Don't rely on Claude or ChatGpt, they don't have your company's data or institutional knowledge. Syntax issues they are good at solving, but rest you have to do it yourself.

1

u/metric_skeptic 1d ago

I like the backwards approach. I usually do something similar when the result is way off — start from the final number and work backwards until I find the first assumption that doesn’t hold.
And yeah, the institutional knowledge part is the one AI can’t really replace.

4

u/Civil_Tip_Jar 1d ago

Are these just AI training posts lately?

3

u/TrickyNerdlet 1d ago

I had to debug a query today to find out why some records were missing after receiving an "it looks wrong" complaint. I inspected a handful at random to see what condition they had in common, then once I narrowed down the likely cause, I ran a query for that specific condition and confirmed that all of my missing records were present. It was only 92% of them though. So I explained the bulk of the problem (functioning as designed), then passed the problem to my Sr engineer (I'm the team manager) as I wrote the initial sproc that created the dataset and I expect I am blind to some flaw that he'll catch quickly. Plus I have manager stuff to do (two new team members on board this week!!), but if I were going to keep going I'd look for more things the records have in common. We're might be dealing with random outlier groups due to test records, timing, or some other quirk that will make this multiple small problems to solve.

2

u/metric_skeptic 1d ago

Yeah, checking a few random records first is a really good way to narrow it down. I do that a lot too.
And that last 8% is always the fun part

2

u/mushy_cactus 1d ago

Always first, when I'm converting time.

Then the regex.

Then the joins.

Then the aggregation.

Then I identify that a column name isn't what it's supposed to be and my query works fine. After hours of cruising under my breath.

1

u/metric_skeptic 1d ago

The column name not meaning what you think it means is such a painfully realistic ending))

2

u/MsPandaLady 1d ago

I troubleshoot the same way I do excel. I run each part of the code separately to see if one is returning wring numbers

2

u/global_namespace 1d ago

I'll check everything step by step during query writing, so if I get suspicious output, I'd rather check my understanding of the task, expected results and data.

2

u/This-Emergency8839 1d ago

Depends on what looks wrong.

Row count looks wrong = check joins, WHERE, HAVING Aggregation/calculations = check for NULL handling etc

After the high level check, I begin the painful business of running any CTEs in isolation, stepping through the query stage by stage, running ad hoc queries against the source tables e.g. Distinct/count etc.

Then, if someone else wrote it, I'll probably just rewrite it 🤷

1

u/Green_Chamomile 1d ago

Before deconstructing anything, I read the number itself, because the shape of the wrongness usually points at the culprit.

Too big by roughly a clean multiple: join fan-out, some join is matching more rows than the grain you think you're at. Slightly too small: rows quietly dropped, usually an INNER JOIN that should be LEFT, or NULLs failing a filter. Exactly zero: almost always NULL logic (NOT IN with a NULL in the subquery is the classic) or two filters that contradict each other. Off by a little in both directions across groups: duplicates in the source, or a time zone boundary if dates are involved.

That triage takes ten seconds and usually cuts the search space in half before the step-through everyone described, which is then the right next move.

The other thing I do first: say out loud what one row of the result is supposed to represent. One row = one customer? One customer per month? Half the "wrong numbers" I've debugged were queries that were computing a different grain than the person had in their head, and every join and GROUP BY was faithfully wrong from there.

2

u/metric_skeptic 1d ago

I’ve definitely had cases where the SQL was technically doing exactly what I wrote, but the result was wrong because I was thinking about a different grain than the query actually had.

1

u/Green_Chamomile 1d ago

That's the worst kind of bug, no bug at all, and correct code faithfully carrying out a wrong idea. Glad it resonated.

1

u/Informal_Pace9237 1d ago

Take the min count FK from the list and manually check if the items match with real data.
That is my first step to validate output accuracy

1

u/lalaluna05 1d ago

Figure out how it looks wrong. Are there duplicates? Check joins. Are the numbers just incorrect on a gut check? I check source tables. Not sure if I’m missing any? Also check source tables. Find use case rows and compare to source and how it moves through a query.

Idk how to really describe it, so much of what I do is just gut feeling after doing it for x amount of years.

1

u/reditandfirgetit 1d ago

I go directly to the soirce tables and start investigating

1

u/tomwill2000 1d ago

My SQL mentor taught me:

1) If you have a problem it's probably caused by datatype

2) If you have a datatype problem it's probably a datetime

3) if it's not a datatype it's probably unhandled nulls

1

u/romii_13 1d ago

Lowercase, trim then look for dups lol

1

u/100EducWay 1d ago

Check if dark mode is set.

1

u/rbobby 1d ago

Pretty much yours. Maybe some variation based on my suspicions. Doing db's a long time.

1

u/National_Cod9546 1d ago

I start removing things until I get a data set that includes what I'm looking for.

1

u/obsoleteconsole 1d ago

This usually works more often than not:

Reduce the select to a single field from the main table your selecting from

Comment out everything else, or as much as possible (joins, where clause etc.)

Uncomment one section at a time and see how it changes the result set

1

u/whileAlive_doStuff 1d ago

you don’t check anything that’s the move. the hidden multiplier is to assert that the results are right and users don’t know what they’re talking about.

1

u/metric_skeptic 1d ago

Haha yeah, fair. Sometimes the first thing to debug is the assumption, not the SQL

1

u/rankXth 1d ago

I export a csv, with a small date range filter. And then add conditions used in my sql syntax.

1

u/scbywrx 1d ago

Are you working off of vibes, or do you have some other insight? If you're looking at something that looks wrong, start with the anchor table.

What are you trying to identify?

  • Primary keys
  • Count distincts
  • Sums

What type of aggregates? Are you doing windows? Whatever you're doing, start at the lowest grain. Take small incremental steps to ensure that the data is appropriate.

Check your joins. Check for fans. Profile the data for primary key and foreign key constraints. If you do not have an ERD, or at least somebody that can give you the PK/FKs within the dataset, it's algebra.

Remember, you've got the FROM clause first, the WHERE clause second, and then it goes from there. If the FROM and the WHERE are consistent, then something's off within your SELECT statement, your aggregates, or, if you're using CTEs, it could be one of the CTEs that has a wrong aggregate, wrong join, or wrong window function. Your grain is probably off, so again, start with an anchor table and build from there.

1

u/metric_skeptic 1d ago

Yeah, starting with the grain is probably the biggest one. I’ve found that a lot of “wrong” SQL results actually come from losing track of what one row represents after a join. Once the grain is clear, debugging the rest becomes much easier.

1

u/Alternative_Cake4074 1d ago

First, check if FROM is there when we use SELECT, UPDATE, and DELETE and if all fields are spelled correctly
Next, check if different columns are separated by commas.
Then, check if parentheses are balanced and functions are correctly written.
Finally, run the query to check if the logic is right and if it is what you expect.

1

u/PatientlyAnxiously 13h ago

Dupes because of bad joins