Reputation: 496
I am trying to break the table into 2 parts. (SQL Server 2017) this is my code:
SELECT TOP COUNT(*)/2 TargetColumn
FROM SomeTable
The error message is:
Incorrect syntax near 'COUNT'
TOP doesn't allow me to do that. expressions using fixed numbers aka 2000/2 works, but the above one using COUNT does not.
I have searched StackOverflow but have found only this post that is relevant, which has 2 answers, one of which was branded "dangerous", and the second one I did not understand.
Upvotes: 0
Views: 88
Reputation: 27202
You can't do it in a single query, you need to get the rowcount and then use that for your top
query e.g.
DECLARE @NumRows INT;
SELECT @NumRows = COUNT(*)/2
FROM SomeTable;
SELECT TOP(@NumRows) TargetColumn
FROM SomeTable;
This is because TOP
is a simple function designed to limit the number of rows returned. Having to count the rows requires all rows to be returned which is a contradiction.
If you wish to perform this operation in a single query please see @GMB's answer.
For the table I tested on, this solution took 28% and GMB's took 72% without an order by. If you add an order by this solution took 52% and GMB's took 48%. So the best performing query depends on your specific scenario.
Upvotes: 1
Reputation: 222432
You can do this in a single query using window functions:
select targetcolumn
from (
select
targetcolumn,
row_number() over(order by somecol) rn,
count(*) over() cnt
from sometable
) t
where rn <= cnt / 2
The subquery performs a window count()
of all records in the table, and ranks records with row_number()
. Then, the outer query filters on the bottom half.
Note that using TOP
without an ORDER BY
clause does not really make sense: the ordering of the records is inherently undefined unless explicitly specified, so this results in an undefined set of rows being returned (although with a fixed number of records). I assumed that you have a column for ordering, and called it somecol
in the above query.
Upvotes: 1