2013-05-27 2 views
1

Мой запросSQL Server агрегатная функция ошибка запроса

SELECT TOP 1 *, COUNT(*) AS totalRun 
FROM history 
ORDER BY starttime DESC` 

Предполагаемый результат все данные из 1 строки в таблице истории с последними starttime и поле totalrun с общим количеством записей, но ... Я получаю следующую ошибку.

Msg 8120, Level 16, State 1, Line 1
Колонка 'history.id' недопустим в списке выбора, поскольку он не содержится ни в статистической функции или предложения GROUP BY.

Что я делаю неправильно?

EDIT
пример результата: expected result Это все поля строки с последней STARTTIME в таблице истории с полем дополнительного COUNT «totalRun»

+1

Вы забыли предложение 'group by'. –

ответ

5

Заполнители могут быть выражены только в двух случаях.

  1. Где у вас есть GROUP BY заявления
  2. Где вы используете пункт OVER

Следующие даст вам самое последнее время начала и количество строк в вашей исходной таблице, которые разделяют, что начало время ...

SELECT 
    starttime, 
    COUNT(*) AS row_count 
FROM 
    history 
GROUP BY 
    starttime 
ORDER BY 
    starttime DESC 

В этой структуре только поля вы можете выбрать приведены в заявлении GROUP BY(и у вас может быть несколько) или агрегаты * (например, SUM(), COUNT() и т. д.).

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

SELECT 
    *, 
    COUNT(*) OVER (PARTITION BY 1) AS row_count 
FROM 
    history 
ORDER BY 
    starttime DESC 

Поскольку это не использует GROUP BY, вы можете также выбрать *, а не только ТЕ полей вы группирование по.

Если вам нужно что-то другое, пожалуйста, не могли бы вы включить некоторые примеры данных и результатов вы желаете?

+0

+1 ... Подзаголовок '(SELECT COUNT (*) FROM history)' также может использоваться, но 'OVER (PARTITION BY 1)' быстрее и лучше. –

+0

Результат будет таким же, как этот запрос: MySQL 'SELECT *, COUNT (*) FROM history ORDER BY starttime LIMIT 0,1' Я просто не знаю, как это сделать в mssql –

+0

@GertKommer - MySQL позволяет включать агрегированные функции без' GROUP BY' и включить поля, которые не были сгруппированы. Однако это довольно необычно, и в документации MySQL даже указано, что поведение во многих случаях является произвольным. В MSSQL требуемый синтаксис гораздо более явный, не дает произвольного поведения и на самом деле больше связан с другими диалектами SQL. Использование предложения 'OVER', похоже, соответствует вашему описанию. – MatBailie

3

Вы либо агрегатными или групп по столбцу. У вас есть столбцы, которые не являются ни

SELECT TOP 1 
    starttime, COUNT(*) AS totalRun 
FROM history 
GROUP BY starttime, foo 
ORDER BY starttime DESC; 

Если вам нужен столбец foo, а затем добавить его следующим образом

SELECT TOP 1 
    starttime, foo, COUNT(*) AS totalRun 
FROM history 
GROUP BY starttime, foo 
ORDER BY starttime DESC, foo; 
+2

Op описывает 'и поле totalrun с общим количеством записей'. Я понимаю, что OP хочет «COUNT (*) OVER (PARTITION BY 1)»? – MatBailie

+0

@ Dems: может быть так просто. Хорошая точка зрения. Сделайте свой ответ? – gbn

0

Я не мог unerstand требования надлежащим образом. Почему вы используете top 1 со счетом (*) и без предложения group by.

Если вы хотите, чтобы результат TotalRuns зарабатывал на последнюю дату, то вы можете использовать этот запрос

SELECT TOP 1 starttime, COUNT(1) AS totalRun 
      FROM history Group by starttime ORDER BY starttime DESC 
0

Если это требование:

Предполагаемый результат все данные из 1 строки в таблице истории с последними STARTTIME и fieldtotalrun с общим количеством записей,

выбрать топ 1 * от (Select * из истории где время_запуска = (выберите не более (время_запуска) из истории)) я полное внешнее соединение (выберите кол (1) подсчет, не более (время_запуска) sttime, как fieldtotalrun из истории) J на ​​I .starttime = j.sttime

Смежные вопросы