Counting rows and summary types

Why does the Count summary in my saved search return fewer than the number of rows?

Updated
saved-searchsummarycountcount-distinctinternalidsilent-failurereporting

Why does the Count summary in my NetSuite saved search return fewer than the number of rows?

Because Count is COUNT(DISTINCT), not a row count. It counts how many different values a column produces, so Count of {internalid} on a transaction search reports distinct transactions while the search returned lines. A Formula(Numeric) column of 1 summarised as Sum is the row count.

Because the Count summary is COUNT(DISTINCT expr), not a count of rows. It reports how many different values the column produces. On a transaction search, Count of {internalid} therefore reports the number of distinct transactions, while the search itself returns one row per line.

The two controls that settle it

Both were run on the same ungrouped transaction search, changing nothing but the column.

Count of Formula(Numeric) = 1                    ->  1
Count of Formula(Numeric) = MOD({internalid},3)  ->  3

A formula that is the constant 1 has exactly one distinct value, and Count returns 1. A formula engineered to have exactly three distinct values returns 3. Neither number has anything to do with how many rows the search matched, and the search matched a great many. There is no ambiguity left after those two lines.

Count on {internalid} is the most common way people count rows in a saved search, and it is the one place the wrong answer is least visible, because the number it returns is large and plausible. In the account tested it undercounted the rows the search actually returned by nearly five times. Nothing marks the column as distinct-counting; the summary type is called Count and that is all it is called.

Count of {line} is no better. It returns the number of distinct line numbers present in the result set, which came back smaller again than the distinct-transaction figure by well over an order of magnitude, and which answers nothing anyone asks.

The same search, three different answers

This is the shape worth internalising. One grouped search, one row per bucket, three measures sitting side by side, all three literally correct:

The figures below are invented round ones. The shape of the table, and the fact that the third column reads 1 on every row, is what was measured.

bucket     Count of {internalid}   Sum of Formula 1   Count of Formula 1
notnull                   20,000             90,000                    1
null                      30,000            110,000                    1

Column two counts distinct transactions. Column three counts rows. Column four counts distinct values of a constant, which is one, forever, in every bucket of every search you will ever run. Only one of the three answers the question "how many rows are in this bucket", and none of the three is labelled in a way that tells you which.

Where this reaches production

A summary saved search built in the UI and exported with the results page Export - CSV button carries the same gap into a file that someone else will read. The export had a Type column grouped, a Count of Internal ID, and a Sum of a Formula(Numeric) column containing 1, each with a custom label, and every label survived into the header exactly as typed.

Illustrative round numbers again, real column layout:

probe_type_label,probe_count_label,probe_rowcount_label
Invoice,2000,17000

On one transaction type in that export the two numeric columns differed by more than eight times, in adjacent columns of the same row of the same report. Both columns are plausibly labelled. Only one of them is a row count.

The SuiteQL side has its own number that looks like a row count and is not one, by a completely different mechanism: totalResults in the REST envelope.

How to tell if you are affected

Open any saved search that reports a count and look at what the Count summary is attached to. If it is {internalid}, or any other column whose value repeats across the lines of one record, the number is distinct records, not rows.

The one-minute test: add a second results column, Formula(Numeric), formula 1, summary Sum, and run the search again. If the two totals agree, your result set has one row per record and the Count was harmless. If they disagree, every figure downstream of that Count is wrong, and has been for as long as the search has existed.

Scope: one sandbox account on NetSuite 2026.1, Administrator role, transaction record type. The Count and Sum probes were built and run ad hoc through the SuiteScript search engine (nlapiCreateSearch / runSearch) with nothing saved. The export was UI-driven, from a summary saved search created for the probe and deleted afterwards.

How this was established

3 probe runs against one NetSuite 2026.1 sandbox account on the Administrator role, through the saved search UI and the SuiteScript search engine. Where this page draws a boundary around a finding, that boundary is the edge of what was actually run.

Related

From the blog