2010-09-22 9 views
9

È possibile utilizzare COUNT in una query con una clausola HAVING in modo che COUNT restituisca il numero di righe? Quando provo, sto ottenendo il conteggio del numero di volte che l'ID si presenta nella tabella. Ecco l'interrogazione:COUNT risultati da query SQL con una clausola 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' 

torno 6 righe, che va bene, ma mi piacerebbe arrivare appena tornato il numero 6.

ho scoperto che potevo fare in questo modo, ma era chiedendosi se ci fosse un altro, modo più elegante:

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

Potresti postare sulla struttura del tuo tavolo? Sono confuso sul motivo per cui stai usando min in questa query ... – armonge

+0

Devo trovare il primo pagamento per ogni reclamo (AppID) e se quel pagamento è il primo per quella richiesta e cade con il mese corrente, contarlo. –

risposta

11

Utilizzando COUNT con una clausola GROUP BY fornirà un conteggio per ogni gruppo. Se vuoi il conteggio del numero di gruppi, dovrà essere una query separata (come il tuo esempio CTE).

vorrei solo usare un semplice sottoquery, al posto del 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

Purtroppo questo esempio genera un errore. Sapevo cosa si stava facendo, ma 'ar' ha una soluzione "funzionante". Quindi dovrò dare i punti a quell'individuo. Apprezzo l'aiuto però! –

+0

corretto. Apparentemente non è possibile selezionare da una sottoquery senza nominare la sottoquery. (E non puoi usare una subquery in una dichiarazione "WHERE ... IN" _with_ un nome) – bdukes

+0

Ok, l'ho dato a te, come ho notato dopo che Emtucifor ha portato il problema DateTime e BETWEEN, l'altro poster stava usando FRA . Anche se questo potrebbe funzionare con il tipo di dati DATE più recente, anche la porzione temporale deve essere presa in considerazione. –

4

È inoltre possibile utilizzare una subquery.

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

Supponendo di avere una tabella con l'elenco distinto di valori col_appid chiamato App, questa query funziona anche e può essere una migliore performance, anche:

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' 

Se non v'è alcuna tabella App è possibile sostituire (SELECT DISTINCT col_appid FROM tbl_ui_paymentstubs) A ma non funzionerà altrettanto bene. Potrebbe ancora essere un concorrente rispetto alle altre query fornite.

Altre note:

  • Non c'è bisogno di fare isnull(column, 0) > 0 perché column > 0 già esclude NULL.

  • @ ar e di query @bdukes' non hanno bisogno di nulla nella clausola SELECT interna, si può solo essere selezionate 1 che può essere un miglioramento delle prestazioni (nient'altro modifiche)

  • Spero che ci sia un vincolo su col_payment_issued_date in modo che i valori non abbiano una porzione temporale come 11:23 AM, altrimenti la clausola BETWEEN alla fine non estrarrà i dati corretti per l'intero mese.

Aggiornamento

  • Per quello che vale, il formato della data '20100901' funzionerà ovunque, con qualsiasi lingua o impostazione DATEFIRST. Ti incoraggio a prendere l'abitudine di usarlo. Altri formati come "09/01/2010" o "2010/09/01" e così via possono mettere insieme il mese e il giorno.

@DScott detto:

C'è un tbl_Application, ma in questo caso non viene utilizzato. Potrei unirmi a questo, ma sto solo contando i pagamenti per questa query quindi non è necessario.

Ti dispiacerebbe provare la mia domanda e fornirmi un feedback sulle sue prestazioni rispetto agli altri metodi? Spero che anche con il join aggiuntivo nella query, funzioni abbastanza bene.

+0

Grazie per le informazioni. Hai ragione riguardo al problema TRA BRA, non l'ho notato che nella soluzione originale che ho scelto. Ora che l'altro poster ha corretto la loro risposta, l'ho scelto. C'è una tbl_Application, ma in questa istanza non viene utilizzata. Potrei * unirmi ad esso, ma sto solo contando i pagamenti per questa query quindi non è necessario. –

+0

risposta grande, completa, @Emtucifor – bdukes

+0

@bdukes Grazie! – ErikE