Сложный SQL-запрос - PullRequest
       0

Сложный SQL-запрос

0 голосов
/ 04 августа 2011

У меня есть таблица, которая отслеживает электронные письма, отправленные из приложений на моем сервере.Я хотел бы написать запрос, который показывает, сколько писем было отправлено каждым приложением за определенный период времени.Вот таблица:

---------------------------------------------------------- 
|  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 дней, за этот месяц, за последний месяц, за все время.

Я знаюкак выполнить каждый из этих запросов самостоятельно, но я понятия не имею, как это сделать за одну поездку в базу данных.

Например:

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

Я пытался использовать вложенный выбордля каждого подмножества раз, но я не могу использовать 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

Ответы [ 3 ]

3 голосов
/ 04 августа 2011

Я думаю, что гораздо проще выполнить все вычисления даты заранее, тогда вы можете ссылаться на локальные переменные с логическими именами вместо того, чтобы встраивать все вычисления в виде даты / регистра и т. Д. В логику запроса.

Сделанопара предположений здесь.(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 голосов
/ 04 августа 2011

try:

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

ПРИМЕЧАНИЕ: startDateTime и EndDateTime - это ограничения по границам для обрабатываемых записей.

, если вы также хотите установить сегменты вокруг указанных диапазонов даты и времени, вам просто нужноопределить эти диапазоны даты и времени в другой группе по выражению (и вывести это же выражение в предложении select ... в качестве примера, скажем, диапазоны даты и времени являются календарными месяцами ...

   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
1 голос
/ 04 августа 2011

Нечто подобное должно сработать

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...