2012-01-20 2 views
2

У меня есть таблица, в которой я хочу выбрать подмножество столбцов, но также добавить на конце вычисленный столбец на основе того, где вы находитесь в очереди. Есть следующие поля (которые уместно):Проблема с вычисляемым столбцом в SQL

ID: ИНТ, автоматическое приращение, первичный ключ answertime: Дата и время, обнуляемые

По умолчанию, когда что-то передается в очередь, его answertime является NULL. Поэтому я хочу выбрать идентификатор вещи в очереди, а также ее ранг в очереди (т. Е. Ранг 1 - это следующий элемент, который не отвечает и т. Д.). Вот что я думал:

rank - id - COUNT (ids ниже моего id, где answertime не равно null). Тем не менее, у меня проблема с синтаксисом этого запроса:

SELECT id AS outerid, COUNT(
    SELECT * FROM tablename WHERE id<outerid AND answertime IS NOT NULL 
) 
FROM tablename 
WHERE answertime IS NULL; 

Теперь, очевидно, что это неправильно, потому что я довольно уверен, что Вы не можете вставлять отборный внутри агрегатной функции, также листать SELECT и COUNT не работают, поскольку вы не можете вставлять SELECT в эту точку кода (его можно использовать только в предложении WHERE).

Возможно ли это сделать только с помощью SQL или мне нужно добавить некоторую логику на конец программы?

Если это помогает, я делаю это на SQL Server 2008, хотя я сомневаюсь, что это добавит значение.

+1

времени, чтобы дать хороший пример, но посмотреть функцию row_number. Если я правильно вас понял, я думаю, что это будет то, что вы хотите. – HLGEM

ответ

3

Вы можете сделать это, вы просто не можете использовать SELECT * в агрегированном подзапросе. Попробуйте это, который получает значение COUNT как скалярная результат:

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; 

Вам может понадобиться, чтобы выбрать для себя между использованием COUNT(*), COUNT(Id) или какой-либо другой столбец в зависимости от того, что вы действительно после.

+0

А, я вижу, что мне не хватало, когда я пробовал внутренний запрос SELECT; Я пропустил бит outbot из списка tablename, чтобы он мог различать идентификаторы. Благодаря! – wibarr

+0

Или '(SELECT COUNT (answertime) FROM tablename WHERE id

1
SELECT id AS outerid, 
(SELECT COUNT(*) FROM tablename WHERE id < outerid AND answertime IS NOT NULL) AS othercol 
FROM tablename -- ? 
WHERE answertime IS NULL; 

также, где инструкция FROM?

+0

Я добавил оператор FROM к вопросу; Я упростил это из моего фактического запроса и забыл поставить его там. – wibarr

0

Как предложено @HLGEM, для получения ваших результатов вы можете использовать ROW_NUMBER(). Метод включает ранжирование строк в tablename по id без разбиения на разделы и на id с разбиением на разделы на answertime. Разница между рейтингами для каждой строки, где answertime равна NULL, даст вам то же значение, что и значение, которое вы вычисляете, используя COUNT() в подзапросе.

Вот реализация метода:

; 
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