2011-08-04 10 views
0

私は自分のサーバ上のアプリケーションから送信された電子メールを追跡するテーブルを持っています。特定の期間に各アプリケーションによって送信された電子メールの数を示すクエリを書きたいと思います。こちらの表は、次のとおりです。複合SQLクエリ

---------------------------------------------------------- 
| emailID |   SentDT   | ApplicationName | 
---------------------------------------------------------- 
| 1  | 2011-08-04 14:43:31.080 | Term Form | 
---------------------------------------------------------- 
| 2  | 2011-08-04 13:59:46.062 | Term Form | 
---------------------------------------------------------- 
| 3  | 2011-08-03 10:38:15.015 | Request Form | 
---------------------------------------------------------- 
| 4  | 2011-08-03 05:52:29.005 | Term Form | 
---------------------------------------------------------- 
| 5  | 2011-08-01 19:58:31.094 | Recruiting Form | 
---------------------------------------------------------- 

私は今日送られたメールの数、過去24時間、過去7日間、今月、先月、すべての時間を見たいのですが。

私はこれらのクエリをそれぞれ単独で実行する方法はわかっていますが、データベースへの1回のトリップでどのように実行するのかという手がかりはありません。例えば

-------------------------------------------------------------- 
| ApplicationName | Today | Last24 | Last7days | ThisMonth | 
-------------------------------------------------------------- 
| Term Form  | 2 | 5 | 10  | 19  | 
-------------------------------------------------------------- 
| Request Form | 9 | 18 | 36  | 75  | 
-------------------------------------------------------------- 
| Recruiting Form | 15 | 35 | 100  | 250 | 
-------------------------------------------------------------- 

I回の各サブセットのためのネストされた選択を使用してみましたが、私はネストされた選択にgroup byを使用することはできません。結果を生成しませんマイクエリ:

select COUNT(emailID), ApplicationName, (select COUNT(emailID) from emaillog where SentDT > '08/02/2011') as TwoDaysAgo 
from emaillog 
group by ApplicationName 
order by ApplicationName 
+0

何をする必要がありますか?あなたは何を得ているのですか? – Vinay

答えて

3

トリックを行う必要があります...暦月です論理名の代わりに論理名すべてのdatediff/caseなどの計算をクエリロジックに組み込みます。

ここでは、いくつかの前提を設定しました。 (1)EmailLogのデータが未来であること(2)「過去7日間」とは、今日とそれより前の6日間を意味します。私も総計を含めました - あなたの望む出力にリストされていないのに、COUNT()をサブクエリの外に持ってきているようです。私の仮定が間違っていたとは、アプリケーション名で合計数を必要としない場合

DECLARE @now SMALLDATETIME = SYSDATETIME(); 

DECLARE @today DATE = @now, 
     @24hrsago SMALLDATETIME = DATEADD(DAY, -1, @now); 

DECLARE @7daysago DATE = DATEADD(DAY, -6, @today), 
     @ThisMonth DATE = DATEADD(DAY, 1-DATEPART(DAY, @today), @today); 

--SELECT @now, @today, @24hrsago, @7daysago, @ThisMonth; 

WITH d AS 
(
    SELECT ApplicationName, c = COUNT(*) 
    FROM EmailLog 
    GROUP BY ApplicationName 
), 
g AS 
(
    SELECT 
     ApplicationName, 
     [Today]  = SUM(CASE WHEN SentDt >= @today  THEN 1 ELSE 0 END), 
     [Last24] = SUM(CASE WHEN SentDt >= @24hrsago THEN 1 ELSE 0 END), 
     [Last7Days] = SUM(CASE WHEN SentDt >= @7daysago THEN 1 ELSE 0 END), 
     [ThisMonth] = SUM(CASE WHEN SentDt >= @ThisMonth THEN 1 ELSE 0 END) 
    FROM EmailLog 
    GROUP BY ApplicationName 
) 
SELECT d.ApplicationName, 
    Total = d.c, 
    [Today] = COALESCE(g.[Today], 0), 
    [Last24] = COALESCE(g.[Last24], 0), 
    [Last7days] = COALESCE(g.Last7days, 0), 
    [ThisMonth] = COALESCE(g.ThisMonth, 0) 
FROM d LEFT OUTER JOIN g 
ON d.ApplicationName = g.ApplicationName; 

EDIT

は、クエリが非常に簡単になる:

DECLARE @now SMALLDATETIME = SYSDATETIME(); 

DECLARE @today DATE = @now, 
     @24hrsago SMALLDATETIME = DATEADD(DAY, -1, @now); 

DECLARE @7daysago DATE = DATEADD(DAY, -6, @today), 
     @ThisMonth DATE = DATEADD(DAY, 1-DATEPART(DAY, @today), @today); 

SELECT ApplicationName, 
    [Today]  = SUM(CASE WHEN SentDt >= @today  THEN 1 ELSE 0 END), 
    [Last24] = SUM(CASE WHEN SentDt >= @24hrsago THEN 1 ELSE 0 END), 
    [Last7Days] = SUM(CASE WHEN SentDt >= @7daysago THEN 1 ELSE 0 END), 
    [ThisMonth] = SUM(CASE WHEN SentDt >= @ThisMonth THEN 1 ELSE 0 END) 
FROM EmailLog 
GROUP BY ApplicationName; 

はもちろんのオプション発注します。

2

試してみてください。

Select ApplicationName, COunt(*) numEmails 
    From table 
    where SentDT Between @startDateTime and @EndDateTime 
    Group By ApplicationName 

注:startDateTimeとEndDateTimeが処理されるレコードのoundary制限されています。

指定したdatetiome範囲のバケットを設定したい場合は、式で別のグループのdatetime範囲バケットを定義するだけで済みます(select句で同じ式を出力する必要があります...例としてdatetime範囲は、このような

Select DateAdd(month, DateDiff(month, 0, SentDT), 0) CalMonth, 
     ApplicationName, Count(*) numEmails 
    From table 
    where SentDT Between @startDateTime and @EndDateTime 
    Group By DateAdd(month, DateDiff(month, 0, SentDT), 0), 
      ApplicationName 
+0

これは私が今持っているものですが、それはそれぞれの期間の1つです。私はそれらを1つのクエリにまとめてみたいです – zeroef

+0

これは望ましい結果をもたらしません... [startDateTime]と[EndDateTime]は列であるはずですか?今日はどこですか、過去24時間、過去7日間、今月はあなたの出力に表示されていますか?これは、2つの列を持つ1つの行を返します。 –

+0

[StartDateTimeとenddatetimeは境界の制限値です –

1

何かが、私はそれは、あなたが持つローカル変数を参照することができ、アップフロントのすべての日付の計算を行うためにはるかに簡単だと思う

select 
    ApplicationName, 
    sum(case when daterange = 0 then cnt else 0 end) as Today, 
    sum(case when daterange = 1 then cnt else 0 end) as yesterday, 
    sum(case when daterange <=2 then cnt else 0 end) as Week, 
    sum(case when daterange <=3 then cnt else 0 end) as month, 
    sum(cnt) as AllTime 
from 
    (select 
     ApplicationName, 
     case 
      when days = 0 then '0' 
      when days = 1 then '1' 
      when days <= 7 then '2' 
      when days <= 30 then '3' 
      else 4 
     end as 
     DateRange, 
     Count(emailid) cnt 
    from 
     (select ApplicationName, EmailID, datediff(dd, SentDT, getdate()) as Days 
     from 
      dbo.[YourTableGoesHere] 
     ) as foo 
    Group by 
     ApplicationName, 
     case when days < 1 then '0' 
      when days = 1 then '1' 
      when days <= 7 then '2' 
      when days <= 30 then '3' 
      else 4 
     end) as bar 
group by 
    ApplicationName 
+0

このメソッドを使用して「過去24時間」を取得することはできません.DATEiffでは日付境界のみが考慮されるためです。 –