Проблема с вычисляемым столбцом в SQL - PullRequest
2 голосов
/ 20 января 2012

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

id: int, автоинкремент, первичный ключ время ответа: datetime, nullable

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

rank - id - COUNT (идентификаторы ниже моего идентификатора, где время ответа не равно нулю). Однако у меня возникла проблема с синтаксисом этого запроса:

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, хотя сомневаюсь, что это добавит какую-либо ценность.

Ответы [ 3 ]

3 голосов
/ 20 января 2012

Вы можете сделать это, вы просто не можете использовать 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) или каким-либо другим столбцом, в зависимости от того, что вы действительно хотите.

1 голос
/ 20 января 2012
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 голосов
/ 21 января 2012

Как рекомендует @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
...