2016-04-25 10 views
1

Ich habe ein paar Abfragen, die ich in ONE Abfrage kombinieren möchte, um nicht auf den Server mehrere Male aufrufen müssen.SQL Server: Kombinieren COUNT (*) für verschiedene Tabellen auf einmal

Ein Beispiel für die Abfragen Ich verwende:

SELECT COUNT(*) AS mailCount1 
FROM [WebContact].[dbo].[memberEmails] 
WHERE contactdatetime > '01/01/06' 
    AND contactdatetime < '02/01/06' 

SELECT COUNT(*) AS mailCount2 
FROM [WebContact].[dbo].[otherEmails] 
WHERE contactdatetime > '01/01/06' 
    AND contactdatetime < '02/01/06' 

SELECT COUNT(*) AS mailCount3 
FROM [WebContact].[dbo].[memberEmails] 
WHERE contactdatetime > '02/01/06' 
    AND contactdatetime < '03/01/06' 

SELECT COUNT(*) AS mailCount4 
FROM [WebContact].[dbo].[otherEmails] 
WHERE contactdatetime > '02/01/06' 
    AND contactdatetime < '03/01/06' 

etc etc... 

So wie die obigen Beispiele, was nur, dass Änderungen sind:

  • Die FROM (memberEmails & otherEmails)

  • Die > & < Monate (01/01/06, 02/01/06 | 02/01/06, 03/01/06 | etc ...)

Ist dies mit einer einzigen Abfrage möglich?

+0

Warum ist dies mit 'vb.net' getaggt? Dies ist streng genommen eine SQL-Frage. – Jeroen

Antwort

3

Verwenden Sie zuerst group by und nur zwei Abfragen verwenden:

select year(contactdatetime) as yyyy, month(contactdatetime) as mm, count(*) 
from WebContact].[dbo].[memberEmails] 
group by year(contactdatetime), month(contactdatetime); 

und:

select year(contactdatetime) as yyyy, month(contactdatetime) as mm, count(*) 
from WebContact].[dbo].[otherEmails] 
group by year(contactdatetime), month(contactdatetime); 

Dann, wenn Sie möchten, können Sie diese in einer einzigen Abfrage kombinieren:

select coalesce(me.yyyy, oe.yyyy) as yyyy, coalesce(me.mm, oe.mm) as mm, 
     coalesce(me.cnt, 0) as memberemailcnt, 
     coalesce(oe.cnt, 0) as otheremailcnt 
from (select year(contactdatetime) as yyyy, month(contactdatetime) as mm, count(*) as cnt 
     from WebContact].[dbo].[memberEmails] 
     group by year(contactdatetime), month(contactdatetime) 
    ) me full outer join 
    (select year(contactdatetime) as yyyy, month(contactdatetime) as mm, count(*) as cnt 
     from WebContact].[dbo].[otherEmails] 
     group by year(contactdatetime), month(contactdatetime) 
    ) oe 
    on me.yyyy = oe.yyyy and me.mm = oe.mm; 

Eine full outer join ist nicht erforderlich, wenn beide Tabellen Daten für alle Monate enthalten.

+0

Berücksichtigen Sie eines der Punkte> und StealthRT

+0

Ich kann den letzten nicht auslösen. Obwohl die ersten 2 richtig feuern konnten. – StealthRT

+0

@StealthRT. . . Diese erzeugen separate Zeilen für jedes Jahr/Monat. Das einzige offensichtliche Problem, das ich in der dritten Abfrage sehe, ist, dass 'count (*)' keinen Spaltenalias hat. –

0

Ich habe die Syntax oder die Leistung nicht, aber man kann etwas tun,

 WITH cte (
     countvalue 
     ,description 
     ) 
    AS (
     SELECT COUNT(*) 
      ,'mailCount1' 
     FROM [WebContact].[dbo].[memberEmails] 
     WHERE contactdatetime > '01/01/06' 
      AND contactdatetime < '02/01/06' 

     UNION ALL 

     SELECT COUNT(*) 
      ,'mailCount2' 
     FROM [WebContact].[dbo].[otherEmails] 
     WHERE contactdatetime > '01/01/06' 
      AND contactdatetime < '02/01/06' 

     UNION ALL 

     SELECT COUNT(*) 
      ,'mailCount3' 
     FROM [WebContact].[dbo].[memberEmails] 
     WHERE contactdatetime > '02/01/06' 
      AND contactdatetime < '03/01/06' 

     UNION ALL 

     SELECT COUNT(*) 
      ,'mailCount4' 
     FROM [WebContact].[dbo].[otherEmails] 
     WHERE contactdatetime > '02/01/06' 
      AND contactdatetime < '03/01/06' 
     ) 

    SELECT mailCount1 
    ,mailCount2 
    ,mailCount3 
    ,mailCount4 
FROM (
    SELECT countvalue 
     ,description 
    FROM cte 
    ) d 
pivot(max(countvalue) FOR description IN (mailCount1, mailCount2, mailCount3, mailCount4)) piv; 

this helps ..

+0

Bessere Syntax wäre, dass zuerst in der FROM wählen und CROSS JOIN für die anderen verwenden. –

+0

Hum ... scheint nicht zu funktionieren. – StealthRT

+0

siehe aktualisierte Antwort, änderte es, um CTE anstelle von Unterabfrage in Auswahl zu verwenden. – Glk

0
declare @emailCount table(tablename varchar(20), year int, month int, qty int) 

insert into @emailCount 
select 'memberEmails', year(contactdatetime), month(contactdatetime), count(*) 
from [WebContact].[dbo].[memberEmails] 
group by year(contactdatetime), month(contactdatetime) 

insert into @emailCount 
select 'otherEmails',year(contactdatetime), month(contactdatetime), count(*) 
from [WebContact].[dbo].[otherEmails] 
group by year(contactdatetime), month(contactdatetime) 

select tablename, year, month, qty from @emailCount 

WHERE Klausel hinzufügen, wenn Datumsbereiche beschränken benötigt. (Edit - vereinfacht, Jahr() und Monat() Funktionen zu verwenden.)