2010-09-22 7 views
9

Können Sie COUNT in einer Abfrage mit einer HAVING-Klausel verwenden, so dass der COUNT die Anzahl der Zeilen zurückgibt? Wenn ich versuche, bekomme ich die Anzahl der Male, die die ID in der Tabelle angezeigt wird. Hier ist die Abfrage:COUNT Ergebnisse von SQL-Abfrage mit einer HAVING-Klausel

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' 

ich zurück 6 Reihen, was in Ordnung ist, aber ich möchte nur die Zahl zurück 6.

Ich fand ich es auf diese Weise tun konnte, war aber fragen, ob es eine andere war, eleganteren Weg:

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

Könnten Sie bitte über Ihre Tabellenstruktur schreiben? Ich bin verwirrt über, warum Sie min in dieser Abfrage verwenden ... – armonge

+0

Ich muss die früheste Zahlung für jeden Anspruch (AppID) finden und wenn diese Zahlung die erste für diesen Anspruch ist und fällt mit dem aktuellen Monat, zählen Sie es. –

Antwort

11

COUNT mit einer GROUP BY Klausel verwenden für jede Gruppe eine Zählung liefert. Wenn Sie die Anzahl der Gruppen zählen möchten, muss dies eine separate Abfrage sein (wie in Ihrem CTE-Beispiel).

Ich würde nur eine einfache Unterabfrage verwenden, anstelle des 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

Dieses Beispiel wie es ist, löst leider einen Fehler aus. Ich wusste, worauf du hinaus willst, aber "ar" hat eine "funktionierende" Lösung. Also muss ich dem Individuum die Punkte geben. Ich schätze die Hilfe jedoch! –

+0

Behoben. Anscheinend können Sie nicht aus einer Unterabfrage auswählen, ohne die Unterabfrage zu benennen. (Und Sie können eine Unterabfrage in einer 'WHERE ... IN' Anweisung _mit_ einem Namen nicht verwenden) – bdukes

+0

Ok, ich habe es Ihnen gegeben, als ich merkte, dass nachdem Emtucifor die DateTime und BETWEEN Ausgabe angesprochen hatte, das andere Plakat BETWEEN benutzte . Während dies mit dem neueren DATE-Datentyp funktionieren kann, muss auch der Zeitabschnitt berücksichtigt werden. –

4

Sie können auch eine Unterabfrage verwenden.

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

Vorausgesetzt, dass Sie eine Tabelle mit der eindeutigen Liste der col_appid Werte genannt App haben, diese Abfrage funktioniert auch und kann eine bessere Leistung sein, auch:

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' 

Wenn es keine App-Tabelle ist, können Sie ersetzen (SELECT DISTINCT col_appid FROM tbl_ui_paymentstubs) A aber das wird nicht so gut funktionieren. Es könnte immer noch ein Anwärter im Vergleich zu den anderen gestellten Fragen sein.

Andere Anmerkungen:

  • Sie brauchen nicht isnull(column, 0) > 0 weil column > 0 bereits ausgeschlossen NULLs zu tun.

  • @ ar des und @bdukes Anfragen in der inneren SELECT-Klausel nicht etwas brauchen, können sie nur SELECT 1 sein, die eine Leistungsverbesserung (sonst nichts ändert)

  • Ich hoffe, es sein kann, ist eine Einschränkung auf col_payment_issued_date, so dass Werte keinen Zeitabschnitt wie 11:23 Uhr haben, andernfalls wird Ihre BETWEEN-Klausel schließlich nicht die richtigen Daten für den gesamten Monat abrufen.

aktualisieren

  • Für das, was es wert ist, wird das Datumsformat '20100901' überall arbeiten, mit einer beliebigen Sprache oder DATEFIRST Einstellung. Ich ermutige Sie, sich daran zu gewöhnen, es zu benutzen. Andere Formate wie '09/01/2010 'oder' 2010/09/01 'usw. können den Monat und den Tag durcheinander bringen.

@DScott sagte:

Es gibt eine tbl_Application, aber in diesem Fall nicht verwendet wird. Ich könnte mich ihm anschließen, aber ich zähle nur Zahlungen für diese Abfrage, so dass es nicht erforderlich ist.

Würde es Ihnen etwas ausmachen, meine Abfrage zu testen und mir Feedback zu ihrer Leistung im Vergleich zu den anderen Methoden zu geben? Ich hoffe, dass selbst mit der zusätzlichen Verknüpfung in der Abfrage, es ziemlich gut funktioniert.

+0

Danke für die Info. Sie haben Recht mit der BETWEEN-Frage, die ich nicht bemerkt habe, als in der ursprünglichen Lösung, die ich ausgewählt habe. Jetzt, wo das andere Plakat ihre Antwort korrigiert hat, habe ich diese ausgewählt. Es gibt eine tbl_Application, aber in diesem Fall wird nicht verwendet. Ich * könnte * dazu beitragen, aber ich zähle nur Zahlungen für diese Abfrage, so dass es nicht erforderlich ist. –

+0

große, gründliche Antwort, @Emtucifor – bdukes

+0

@bdukes Danke! – ErikE