2010-09-22 7 views
9

Можете ли вы использовать COUNT в запросе с предложением HAVING, чтобы COUNT возвращал количество строк? Когда я пытаюсь, я получаю подсчет количества раз, когда идентификатор появляется в таблице. Вот запрос:COUNT результат SQL Query с предложением HAVING

SELECT col_appid, min(col_payment_issued_date) as PayDate 
FROM tbl_ui_paymentstubs 
WHERE isnull(col_payment_amount,0) > 0 
GROUP BY col_appid 
HAVING min(col_payment_issued_date) >= '09/01/2010' and min(col_payment_issued_date) <= '09/30/2010' 

я вернусь 6 строк, что это хорошо, но я хотел бы просто вернуться номер 6.

я обнаружил, что могу сделать это так, но интересно, существует ли другой, более удобный способ:

WITH Claims_CTE(AppID, PayDate) as 
( 
SELECT col_appid, min(col_payment_issued_date) as PayDate 
FROM tbl_ui_paymentstubs 
WHERE isnull(col_payment_amount,0) > 0 
GROUP BY col_appid 
HAVING min(col_payment_issued_date) >= '09/01/2010' and min(col_payment_issued_date) <= '09/30/2010' 
) 
SELECT count(AppID) as Amount from Claims_CTE 

`

+0

Не могли бы вы рассказать о своей структуре стола? я смущен о том, почему вы используете min в этом запросе ... – armonge

+0

Мне нужно найти самую раннюю оплату за каждое требование (AppID), и если этот платеж является первым для этого требования и падает в текущем месяце, подсчитайте его. –

ответ

11

Использование COUNT с пунктом GROUP BY обеспечит подсчет для каждой группы. Если вы хотите подсчитать количество групп, это должен быть отдельный запрос (например, ваш пример CTE).

Я просто хотел бы использовать простой подзапрос, а КТР:

SELECT COUNT(*) FROM 
(SELECT col_appid, min(col_payment_issued_date) as PayDate 
    FROM tbl_ui_paymentstubs 
    WHERE isnull(col_payment_amount,0) > 0 
    GROUP BY col_appid 
    HAVING 
    min(col_payment_issued_date) >= '09/01/2010' 
    and min(col_payment_issued_date) <= '09/30/2010') Claims 
+0

Этот пример как есть, к сожалению, вызывает ошибку. Я знал, к чему вы клоните, но «ар» имеет «рабочее» решение. Поэтому я должен буду дать баллы этому человеку. Я ценю помощь, хотя! –

+0

Исправлено. По-видимому, вы не можете выбрать из подзапроса, не назвав подзапрос. (И вы не можете использовать подзапрос в операторе 'WHERE ... IN' _with_ a name) – bdukes

+0

Хорошо, я дал его вам, поскольку я заметил, что после того, как Emtucifor поднял вопрос DateTime и BETWEEN, другой плакат использовал BETWEEN , Хотя это может работать с более новым типом данных DATE, необходимо также учитывать временную часть. –

4

Вы также можете использовать подзапрос.

SELECT count(*) as Amount 
FROM (
    SELECT col_appid FROM tbl_ui_paymentstubs 
    WHERE isnull(col_payment_amount,0) > 0 
    GROUP BY col_appid 
    HAVING min(col_payment_issued_date) BETWEEN '09/01/2010' AND '09/30/2010' 
) Claims 
2

Предполагая, что у вас есть таблица с отчетливым список col_appid значений, называемых App, этот запрос также работает и может быть лучше производительность тоже:

SELECT Count(*) 
FROM 
    App A 
    CROSS APPLY (
     SELECT TOP 1 col_payment_issued_date 
     FROM tbl_ui_paymentstubs P 
     WHERE 
     P.col_payment_amount > 0 
     AND A.col_appid = P.col_appid 
     ORDER BY col_payment_issued_date 
    ) X 
WHERE 
    X.col_payment_issued_date >= '09/01/2010' 
    AND X.col_payment_issued_date < '10/01/2010' 

Если нет таблицы App можно заменить (SELECT DISTINCT col_appid FROM tbl_ui_paymentstubs) A, но это не сработает. Он по-прежнему может быть соперником по сравнению с другими заданными вопросами.

Другие ноты:

  • Вам не нужно делать, потому что isnull(column, 0) > 0column > 0 уже исключает NULLs.

  • @ ар-х и запросы @bdukes' ничего во внутреннем ЗЕЬЕСТЕ не нужно, они могут быть просто ВЫБРАТЬ 1, который может быть повышение производительности (больше ничего не изменения)

  • Я надеюсь, что есть ограничение на col_payment_issued_date, чтобы значения не имели временной части, такой как 11:23 AM, в противном случае предложение BETWEEN в конечном итоге не потянет правильные данные за весь месяц.

Update

  • Для чего это стоит, формат даты '20100901' будет работать везде, с любого языка или настройки DATEFIRST. Я призываю вас привыкнуть к его использованию. Другие форматы, такие как '09/01/2010 'или' 2010/09/01 'и т. Д., Могут перевести месяц и день.

@DScott сказал:

Существует tbl_Application, но в данном случае не используется. Я мог бы присоединиться к нему, но я просто подсчитываю платежи за этот запрос, поэтому он не требуется.

Не могли бы вы попытаться мой запрос и дать мне отзыв о его качестве по сравнению с другими методами? Я надеюсь, что даже с дополнительным присоединением к запросу он работает очень хорошо.

+0

Спасибо за информацию. Вы правы в вопросе «МЕЖДУ», я не заметил, чем в оригинальном решении, которое я выбрал. Теперь, когда другой плакат исправил свой ответ, я выбрал его. Существует tbl_Application, но в этом случае не используется. Я * мог * присоединиться к нему, но им просто подсчитывать платежи за этот запрос, чтобы он не требовался. –

+0

отличный, тщательный ответ, @Emtucifor – bdukes

+0

@bdukes Спасибо! – ErikE