Значения из двух групп путем выбора операторов в один - PullRequest
0 голосов
/ 21 сентября 2011

У меня есть таблица для регистрации вызовов методов.В нем есть столбцы LogId, MethodId, DateTime.

Мне нужно написать оператор выбора, который подсчитывает все журналы для определенных идентификаторов методов за определенный период времени, а также показывает количество журналов для конкретных методов за другое время.period.

Первый бит прост:

select
    l.[MethodId],
    count(l.[LogId]) as [Count]
from
    [Log] l (nolock)
where
    l.[DateTime] between @from and @to
    and l.[MethodId] in @methodIds
group by
    l.[MethodId]

Но теперь мне нужен второй столбец в этой таблице, Previous, который выглядел бы так, если бы он был в отдельной инструкции:

select
    l.[MethodId],
    count(l.[LogId]) as [Previous]
from
    [Log] l (nolock)
where
    l.[DateTime] between @before and @from 
    and l.[MethodId] in @methodIds
group by
    l.[MethodId]

Не все методы будут иметь журналы за два периода времени, поэтому было бы неплохо, если бы объединение вставило 0 в столбцы count / previous в этих случаях вместо того, чтобы они были нулевыми.Это нормально, если у метода нет журналов в любой из этих периодов.

Я хочу видеть MethodId, Count, Previous в одной таблице.Как мне это сделать?

Ответы [ 3 ]

2 голосов
/ 21 сентября 2011

Что-то вроде:

select 
    l.[MethodId], 
    sum(case when datetime between @from and @to then 1 else 0 end) as count,
    sum(case when datetime between @before and @from then 1 else 0 end) as previous
from 
    [Log] l
where 
    l.[DateTime] between @before and @to 
    and l.[MethodId] in @methodIds 
group by 
    l.[MethodId] 

Предложение BETWEEN в каталоге where не влияет на вывод, но может повлиять на производительность, если у вас есть индекс для datetime.И если эта таблица может стать большой, у вас, вероятно, должен быть такой индекс.

1 голос
/ 21 сентября 2011

Попробуйте использовать полное внешнее соединение:

DECLARE @from1 DATETIME, 
    @from2 DATETIME,
    @to1 DATETIME,
    @to2 DATETIME;

SELECT @from1 = '2011-01-01T00:00:00.000', 
    @to1 = '2011-01-31T23:59:59.997',
    @from2 = '2011-02-01T00:00:00.000',
    @to2 = '2011-02-28T23:59:59.997';


SELECT ISNULL(a.MethodID, b.MethodID) MethodID
    ,ISNULL(a.[Count]) CountA
    ,ISNULL(b.[Count]) CountB
FROM
(
select
    l.[MethodId],
    count(l.[LogId]) as [Count]
from
    [Log] l (nolock)
where
    l.[DateTime] between @from1 and @to1
    and l.[MethodId] in @methodIds
group by
    l.[MethodId]
) a 
FULL OUTER JOIN
(
select
    l.[MethodId],
    count(l.[LogId]) as [Previous]
from
    [Log] l (nolock)
where
    l.[DateTime] between @from2 and @to2 
    and l.[MethodId] in @methodIds
group by
    l.[MethodId]
) b
ON a.MethodID = b.MethodID
1 голос
/ 21 сентября 2011

Попробуйте это:

select
    l.[MethodId],
    count(isnull(l.[LogId],0)) as [Previous]
from
    [Log] l (nolock)
where
    l.[DateTime] between @before and @from 
    and l.[MethodId] in @methodIds
group by
    l.[MethodId]
...