#35450·TDengine

GROUP BY ... LIMIT n returns all groups when the query has no ORDER BY (3.4.2.5)

Author: alexey-milovidovCreated Aug 31, 2026Updated Aug 31, 2026

Version

  • taosd version: 3.4.2.5.community (TDengine TSDB-OSS tarball)
  • git: c15925333c9fe385902b153879b812c26bc612f7, build: Linux-arm64 2026-08-16 16:59:49
  • Single dnode, stock taos.cfg, Ubuntu 24.04 aarch64

What happens

SELECT ... GROUP BY ... LIMIT n returns every group instead of n rows when the statement has no ORDER BY. Adding ORDER BY, using SLIMIT instead, or wrapping the aggregate in a subquery all restore the limit, so it looks like the limit is dropped when there is no sort node above the aggregate.

Reproduction

sql
CREATE DATABASE limittest;
CREATE TABLE limittest.t (ts TIMESTAMP, g INT, v INT);

1,000 rows across 100 groups:

python
with open('/tmp/lt.csv', 'w') as f:
    for i in range(1000):
        f.write('%d,%d,%d\n' % (1700000000000 + i, i % 100, i))
taos -d limittest -s "INSERT INTO t FILE '/tmp/lt.csv'"
Insert OK, 1000 row(s) affected (0.051393s)

taos -d limittest -s "SELECT g, count(*) FROM t GROUP BY g LIMIT 10"
Query OK, 100 row(s) in set (0.033020s)          <-- expected 10

taos -d limittest -s "SELECT g, count(*) FROM t GROUP BY g ORDER BY g LIMIT 10"
Query OK, 10 row(s) in set (0.003505s)           <-- correct

Expected

10 rows in both cases. LIMIT is documented as "Specify the number of output data, limit_val specifies the number of outputs"; the per-shard behaviour is documented only for PARTITION BY, and this query has none.

Workarounds

Any of these return 10 rows:

sql
SELECT g, count(*) FROM t GROUP BY g ORDER BY g LIMIT 10;
SELECT g, count(*) FROM t GROUP BY g SLIMIT 10;
SELECT * FROM (SELECT g, count(*) FROM t GROUP BY g) LIMIT 10;

Why it matters to us

We hit this adding TDengine to ClickBench, whose query 18 is exactly this shape — GROUP BY two columns with LIMIT 10 and deliberately no ORDER BY. On the full 100M-row dataset that grouping has 24 million groups, so instead of ten rows the server tries to build and ship all 24 million. We had to wrap it in a subquery.