Получение статистических данных, зависящих от времени (счетчиков), по флагу, разбитому по внешнему идентификатору, по нескольким таблицам, возвращенным в одном наборе данных - PullRequest
0 голосов
/ 07 марта 2011

У меня есть таблица элементов, которые разделены на siteId и статус.

CREATE TABLE ItemDetail (
    ItemNumber    long,
    SiteId        int,
    Status        int,
    Created       datetime
)

И еще у меня есть таблица пользователя

CREATE TABLE UserDetail (
    UserId        int,
    Suspended     int
)

Статус имеет 7 возможных значений(0-6), представляющие различные очереди.Давайте назовем эту переменную х.Приостановлено, должно иметь только 0 (активный) или 1 (приостановленный).(не спрашивайте меня, почему это int, я его не строил).Данные отображаются для каждого сайта в настраиваемом периоде времени.По умолчанию 5 дней назад.Давайте назовем эту переменную а.Я хочу вернуть за один вызов набор данных, подобный следующему:

ActiveUserCount        int
SuspendedUserCount     int,
Queue0Count            int,
Queue0TodayCount       int,
Queue1Count            int,
Queue1TodayCount       int,
...

Где QueueXCount - это все за последние сутки по статусу и идентификатору сайта.QueueXTodayCount - это все со статусом x, которое произошло сегодня.До сих пор я запустил такой процесс

CREATE PROCEDURE GetSiteStatistics
    @SiteId       int,
    @Window       int
AS
BEGIN
DECLARE @Today datetime
DECLARE @Tomorrow datetime
DECLARE @CutOff datetime

SET @Today = (CAST(YEAR(getdate()) as varchar) + 
    RIGHT('00' + CAST(MONTH(getdate()) as varchar), 2) + 
    RIGHT('00' + CAST(DAY(getdate()) as varchar), 2))

SET @Tomorrow  = DATEADD(dd, 1, @Today)

SET @CutOff = DATEADD(dd, @Window + 1, @Today) 

DECLARE
    @SuspendedUserCount         int,
    @ActiveUserCount            int,
    @Queue0Count                int,
    @Queue0TodayCount           int,
    ...

SELECT @SuspendedUserCount = count(UserId) FROM UserDetail WHERE Suspended = 1 AND SiteId = @SiteId
SELECT @ActiveUserCount = count(UserId) FROM UserDetail WHERE Suspended = 0 AND SiteId = @SiteId
SELECT @Queue0Count = count(ItemNumber) FROM ItemDetail WHERE Status = 0 AND SiteId = @SiteId   AND Created >= @Today AND Created < @CutOff 
SELECT @Queue0TodayCount = count(ItemNumber) FROM ItemDetail WHERE Status = 0 AND SiteId = @SiteId AND Created >= @Today AND Created < @Tomorrow 
...

SELECT @SuspendedUserCount AS SuspendedUsers, @ActiveUserCount AS ActiveUsers, @Queue0Count AS Queue0, @Queue0TodayCount AS @Queue0Today...
END

Как будто это не достаточно сложно, я использую Fluent Nhibernate.Я не против использования sproc, если это необходимо, но я рассмотрел создание представления с подсчетами по дням, используя его с помощью nhibernate и запроса для выбора по диапазону дат, а затем суммируя суммы, где это необходимо, в коде.

У меня просто ощущение, что я делаю это более сложным, чем нужно.Должен быть лучший способ.

Ответы [ 2 ]

2 голосов
/ 07 марта 2011

Возможно, вы можете использовать это.

declare @SiteId int = 1
declare @Window int = 5

declare @ToDay datetime = dateadd(d, datediff(d, 0, getdate()), 0)
declare @CutOff datetime = dateadd(d, @Window, @ToDay)
declare @Tomorrow datetime = dateadd(d, 1, @ToDay)

select * from
(
  select
    sum(case when Suspended = 0 then 1 else 0 end) as ActiveUserCount,
    sum(case when Suspended = 1 then 1 else 0 end) as SuspendedUserCount
  from UserDetail
  where
    SiteId = @SiteId
) as q1 cross join
(
  select
    sum(case when Status = 0 then 1 else 0 end) as Queue0Count,
    sum(case when Status = 1 then 1 else 0 end) as Queue1Count,
    sum(case when Status = 2 then 1 else 0 end) as Queue2Count,
    sum(case when Status = 3 then 1 else 0 end) as Queue3Count,
    sum(case when Status = 4 then 1 else 0 end) as Queue4Count,
    sum(case when Status = 5 then 1 else 0 end) as Queue5Count,
    sum(case when Status = 6 then 1 else 0 end) as Queue6Count,
    sum(case when Status = 0 and Created < @Tomorrow then 1 else 0 end) as Queue0TodayCount,
    sum(case when Status = 1 and Created < @Tomorrow then 1 else 0 end) as Queue1TodayCount,
    sum(case when Status = 2 and Created < @Tomorrow then 1 else 0 end) as Queue2TodayCount,
    sum(case when Status = 3 and Created < @Tomorrow then 1 else 0 end) as Queue3TodayCount,
    sum(case when Status = 4 and Created < @Tomorrow then 1 else 0 end) as Queue4TodayCount,
    sum(case when Status = 5 and Created < @Tomorrow then 1 else 0 end) as Queue5TodayCount,
    sum(case when Status = 6 and Created < @Tomorrow then 1 else 0 end) as Queue6TodayCount
  from ItemDetail
  where
    Created >= @ToDay and
    Created < @CutOff
) as q2
0 голосов
/ 12 апреля 2011

Я создал вид, используя CTE и сводную точку

CREATE VIEW [dbo].[SiteQueueDailyStatistics]
AS

WITH statCTE AS (
    SELECT
        Count(ItemNumber)as ItemCount,
        SiteId,
        Status,
        DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate)) AS ScanDay
    FROM
        ItemDetail
    group by  SiteId, Status, DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate))
)

SELECT 
    SiteId, 
    ScanDay, 
    ISNULL([0], 0) AS Queue0,
    ISNULL([1], 0) AS Queue1,
    ISNULL([2], 0) AS Queue2,
    ISNULL([3], 0) AS Queue3,
    ISNULL([4], 0) AS Queue4,
    ISNULL([5], 0) AS Queue5,
    ISNULL([6], 0) AS Queue6
FROM 
    statCTE
PIVOT
(
    SUM(ItemCount)
    FOR [Status] IN ([0], [1], [2], [3], [4], [5], [6])
)
AS p


GO

А затем я получаю все свои данные и заполняю составной объект в моей модели, который содержит статистику по нескольким таблицам.

...