2016-04-25 16 views
1

我有幾個查詢,我想合併到一個查詢,以便不必多次呼叫到服務器。SQL Server:一次結合COUNT(*)爲不同表格

我使用的查詢的一個例子:

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... 

所以上面的例子,唯一的改變是:

  • FROMmemberEmails & otherEmails

  • The > & <個月(01/01/06,02/01/06 | 02/01/06,03/01/06 |等等......)

這是可能做一個單一的查詢嗎?

+0

爲什麼標記爲'vb.net'?這完全是一個SQL問題。 – Jeroen

回答

3

首先,使用group by,只使用兩個查詢:

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

和:

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

然後,如果你願意,你可以將其組合到一個查詢:

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; 

如果兩個表都包含所有月份的數據,則不需要。

+0

做任何這些考慮>和 StealthRT

+0

我無法得到最後一個發射。雖然前2個火力很好。 – StealthRT

+0

@StealthRT。 。 。這些產生每年/每月單獨的行。我在第三個查詢中看到的唯一明顯問題是'count(*)'沒有列別名。 –

0

我沒有檢查語法或性能,但你可以做這樣的事情,

 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; 

希望這有助於..

+0

更好的語法是首先在FROM中選擇併爲其他人使用CROSS JOIN。 –

+0

嗡嗡聲...似乎無法得到這個工作。 – StealthRT

+0

請參閱更新的答案,將其更改爲使用CTE而不是select中的子查詢。 – 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條款,如果需要限制日期範圍。 (編輯 - 簡化爲使用年份()和月份()函數。)