2010-09-22 23 views
9

¿Puede usar COUNT en una consulta con una cláusula HAVING para que el COUNT devuelva el número de filas? Cuando lo intento, obtengo el recuento de la cantidad de veces que aparece la identificación en la tabla. Ésta es la consulta:COUNT resulta de SQL Query con una cláusula 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' 

regrese 6 filas, lo cual está bien, pero me gustaría simplemente volver el número 6.

descubrí que podía hacerlo de esta manera, pero estaba preguntándose si había otra manera, más 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

¿Podría publicar sobre la estructura de su mesa? Estoy confundido acerca de por qué está usando min en esta consulta ... – armonge

+0

Tengo que encontrar el primer pago para cada reclamo (AppID) y si ese pago es el primero para ese reclamo y cae con el mes actual, cuéntelo. –

Respuesta

11

Usando COUNT con una cláusula GROUP BY proporcionará un recuento de cada grupo. Si desea contar el número de grupos, tendrá que ser una consulta separada (como su ejemplo de CTE).

me acaba de utilizar una subconsulta simple, en lugar 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

Este ejemplo como está, arroja un error por desgracia. Sabía a dónde llegar, pero 'ar' tiene una solución de "trabajo". Entonces tendré que darle los puntos a esa persona. ¡Agradezco la ayuda sin embargo! –

+0

Reparado. Aparentemente no puede seleccionar de una subconsulta sin nombrar la subconsulta. (Y no puede usar una subconsulta en una instrucción 'WHERE ... IN' _with_ a name) – bdukes

+0

Ok, se lo di, ya que me di cuenta después de que Emtucifor sacó el tema DateTime y BETWEEN, el otro cartel estaba usando BETWEEN . Si bien esto puede funcionar con el tipo de datos DATE más nuevo, también se debe considerar la porción de tiempo. –

4

También puede utilizar una subconsulta.

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

Asumiendo que tiene una tabla con la lista clara de los valores col_appid llamados aplicación, esta consulta también trabaja y puede ser mejor rendimiento, también:

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' 

Si no hay una mesa de aplicaciones se puede sustituir (SELECT DISTINCT col_appid FROM tbl_ui_paymentstubs) A pero eso no funcionará tan bien. Todavía podría ser un contendiente en comparación con las otras consultas dadas.

Otras notas:

  • Usted no tiene que hacer isnull(column, 0) > 0 porque column > 0 ya excluye los nulos.

  • @ ar de y consultas @bdukes' no necesita nada en la cláusula SELECT interna, que sólo puede ser SELECT 1, que puede ser una mejora del rendimiento (nada cambia)

  • espero que haya una restricción en col_payment_issued_date para que los valores no tengan una porción de tiempo como 11:23 AM, de lo contrario, su cláusula BETWEEN eventualmente no extraerá los datos correctos para todo el mes.

actualización

  • Por lo que vale la pena, el formato de fecha '20100901' funcione en todas partes, con cualquier lenguaje o entorno DATEFIRST. Te animo a que adquieras el hábito de usarlo. Otros formatos como '09/01/2010 'o' 2010/09/01 'y así sucesivamente pueden confundir el mes y el día.

@DScott dijo:

Hay una tbl_Application, pero en este caso no se utiliza. Podría unirme a él, pero estoy contando pagos para esta consulta, por lo que no es necesario.

¿Te importaría intentar mi consulta y darme retroalimentación sobre su rendimiento en comparación con los otros métodos? Espero que incluso con la combinación adicional en la consulta, funcione bastante bien.

+0

Gracias por la información. Tiene razón sobre el problema BETWEEN, no lo noté en la solución original que escogí. Ahora que el otro cartel ha corregido su respuesta, elegí esa. Hay una aplicación tbl_, pero en este caso no se usa. Yo * podría * unirme a él, pero estoy contando pagos para esta consulta, por lo que no es obligatorio. –

+0

respuesta excelente y completa, @Emtucifor – bdukes

+0

@bdukes ¡Gracias! – ErikE