Reputation: 276
I have a table that I wish to select a subset of columns from but also add on the end a computed column based upon where you are located in a queue. There are the following fields (that are pertinent):
id: int, auto increment, primary key answertime: datetime, nullable
By default, when something is submitted to the queue, its answertime is NULL. So, I wish to select the ID of the thing in the queue as well as its rank in the queue (i.e. rank 1 is the next item that is unanswered, etc). Here's what I was thinking:
rank - id - COUNT(ids below my id where answertime is not null). However, I'm having an issue with the syntax of this query:
SELECT id AS outerid, COUNT(
SELECT * FROM tablename WHERE id<outerid AND answertime IS NOT NULL
)
FROM tablename
WHERE answertime IS NULL;
Now, obviously, this is wrong because I'm fairly confident you can't embed a select inside of an aggregate function, likewise flipping the SELECT and COUNT doesn't work as you can't embed a SELECT at that point in the code (it can only be used in a WHERE clause).
Is this even possible to do with just SQL or do I need to add some logic on the program end?
If it helps, I'm doing this on SQL Server 2008, although I doubt that would add any value.
Upvotes: 2
Views: 443
Reputation: 77657
As suggested by @HLGEM, you could use ROW_NUMBER()
to obtain your results. The method involves ranking the rows in tablename
by id
without partitioning and by id
with partitioning by answertime
. The difference between the rankings for every row where answertime
is NULL would give you the same value as the one you are calculating using COUNT()
in the subquery.
Here's an implementation of the method:
;
WITH ranked AS (
SELECT
*,
Rnk = ROW_NUMBER() OVER ( ORDER BY id),
PartRnk = ROW_NUMBER() OVER (PARTITION BY answertime ORDER BY id)
FROM tablename
)
SELECT
id, /* AS outerid, if you like */
Cnt = Rnk - PartRnk
FROM ranked
WHERE answertime IS NULL
Upvotes: 0
Reputation: 1977
SELECT id AS outerid,
(SELECT COUNT(*) FROM tablename WHERE id < outerid AND answertime IS NOT NULL) AS othercol
FROM tablename -- ?
WHERE answertime IS NULL;
also, where's the FROM statement?
Upvotes: 1
Reputation: 50825
You can do that, you just can't use SELECT *
in an aggregate sub-query. Try this, which gets the COUNT
value as a scalar result:
SELECT
id AS outerid,
(SELECT COUNT(Id) FROM tablename
WHERE id<outie.id AND answertime IS NOT NULL)
FROM tablename outie
WHERE answertime IS NULL;
You may need to choose for yourself between using COUNT(*)
, COUNT(Id)
or some other column depending on what you're really after.
Upvotes: 3