CRM报告中的SQL查询

时间:2012-11-07 16:28:43

标签: sql dynamics-crm dynamics-crm-2011 dynamic-sql

CRM中的“案例”有一个名为“状态”的字段,有四个选项。

我正在努力  在CRM中构建一个报表,用一年中的每周填写一个表(每行是不同的一周),然后计算每个Status选项的案例数(列将是每个Status选项)。

表格看起来像这样

         Status 1    Status 2    Status 3
Week 1       3         55          4
Week 2       5         23          5
Week 3       14        11          33

到目前为止,我有以下内容:

SELECT 
    SUM(case WHEN status = 1 then 1 else 0 end) Status1,
    SUM(case WHEN status = 2 then 1 else 0 end) Status2,
    SUM(case WHEN status = 3 then 1 else 0 end) Status3,
    SUM(case WHEN status = 4 then 1 else 0 end) Status4,
    SUM(case WHEN status = 5 then 1 else 0 end) Status5
FROM [DB].[dbo].[Contact]

这给了我以下内容:

Status 1   Status 2   Status 3  
   2         43          53

现在我需要以某种方式将其拆分为过去一年的52行,并按日期过滤这些结果(Contact表中的列)。我对SQL查询和CRM有点新意 - 这里的任何帮助都会非常感激。

这是一个包含我的进度和示例数据的SQLFiddle:http://sqlfiddle.com/#!2/85b19/1

2 个答案:

答案 0 :(得分:2)

听起来像是group by a range。诀窍是创建一个代表每个范围的新字段(每年为您一个)并按此分组。

由于您似乎也想要无限范围的日期,因此marc_s有一个很好的总结如何通过一般方式按日期进行分组:SQL group by frequency within a date range

答案 1 :(得分:1)

所以,让我们打破这个:

您希望制作一份报告,针对每个联系人显示注册到该联系人的案例数量,每周分类,分为三列,每列StateCode。< / p>

如果是这种情况,那么您需要为每个联系人提供52个日期记录(或左右)。对于像请求这样的日历,最好有一个单独的日历表,让您可以从中查询。 Dan Guzman有blog entry创建了一个有用的日历表,我将在查询中使用。

WITH WeekNumbers AS
(
    SELECT
        FirstDateOfWeek,
         -- order by first date of week, grouping calendar year to produce week numbers
        WeekNumber = row_number() OVER (PARTITION BY CalendarYear ORDER BY FirstDateOfWeek)
    FROM
        master.dbo.Calendar -- created from script
    GROUP BY
        FirstDateOfWeek,
        CalendarYear
), Calendar AS
(
    SELECT
        WeekNumber =
        (
            SELECT
                WeekNumber
            FROM
                WeekNumbers WN
            WHERE
                C.FirstDateOfWeek = WN.FirstDateOfWeek
        ),
        *
    FROM
        master.dbo.Calendar C
    WHERE
        CalendarDate BETWEEN '1/1/2012' AND getutcdate()
)

SELECT
    C.FullName,
    ----include the below if the data is necessary
    --Cl.WeekNumber,
    --Cl.CalendarYear,
    --Cl.FirstDateOfWeek,
    --Cl.LastDateOfWeek,
    'Week: ' + CAST(Cl.WeekNumber AS VARCHAR(20))
    + ', Year: ' + CAST(Cl.CalendarYear AS VARCHAR(20)) WeekNumber
FROM
    CRM.dbo.Contact C
    -- use a cartesian join to produce a table list
    CROSS JOIN
        (
            SELECT
                DISTINCT WeekNumber,
                CalendarYear,
                FirstDateOfWeek,
                LastDateOfWeek
            FROM
                Calendar
        ) Cl
ORDER BY
    C.FullName,
    Cl.WeekNumber

这与Ben关联的解决方案不同,因为Marc的查询仅返回存在匹配值的周数,而您可能或可能不希望看到没有活动的周数。

如上所示,您的核心联系人表会逐周拆分(或针对您的特定时间段进行更改),您只需为每个StateCode添加一个子查询,即可将列中的细分视为在下面的最终查询中。

WITH WeekNumbers AS
(
    SELECT
        FirstDateOfWeek,
        WeekNumber = row_number() OVER (PARTITION BY CalendarYear ORDER BY FirstDateOfWeek)
    FROM
        master.dbo.Calendar
    GROUP BY
        FirstDateOfWeek,
        CalendarYear
), Calendar AS
(
    SELECT
        WeekNumber =
        (
            SELECT
                WeekNumber
            FROM
                WeekNumbers WN
            WHERE
                C.FirstDateOfWeek = WN.FirstDateOfWeek
        ),
        *
    FROM
        master.dbo.Calendar C
    WHERE
        CalendarDate BETWEEN '1/1/2012' AND getutcdate()
)

SELECT
    C.FullName,
    --Cl.WeekNumber,
    --Cl.CalendarYear,
    --Cl.FirstDateOfWeek,
    --Cl.LastDateOfWeek,
    'Week: ' + CAST(Cl.WeekNumber AS VARCHAR(20)) +', Year: ' + CAST(Cl.CalendarYear AS VARCHAR(20)) WeekNumber,
    (
        SELECT
            count(*)
        FROM
            CRM.dbo.Incident I
            INNER JOIN CRM.dbo.StringMap SM ON
                I.StateCode = SM.AttributeValue
            INNER JOIN 
                (
                    SELECT
                        DISTINCT ME.Name,
                        ME.ObjectTypeCode
                    FROM
                        CRM.MetadataSchema.Entity ME
                ) E ON
                SM.ObjectTypeCode = E.ObjectTypeCode
        WHERE
            I.ModifiedOn >= Cl.FirstDateOfWeek 
            AND I.ModifiedOn < dateadd(day, 1, Cl.LastDateOfWeek)
            AND E.Name = 'incident'
            AND SM.AttributeName = 'statecode'
            AND SM.LangId = 1033
            AND I.CustomerId = C.ContactId
            AND SM.Value = 'Active'
    ) ActiveCases,
    (
        SELECT
            count(*)
        FROM
            CRM.dbo.Incident I
            INNER JOIN CRM.dbo.StringMap SM ON
                I.StateCode = SM.AttributeValue
            INNER JOIN 
                (
                    SELECT
                        DISTINCT ME.Name,
                        ME.ObjectTypeCode
                    FROM
                        CRM.MetadataSchema.Entity ME
                ) E ON
                SM.ObjectTypeCode = E.ObjectTypeCode
        WHERE
            I.ModifiedOn >= Cl.FirstDateOfWeek 
            AND I.ModifiedOn < dateadd(day, 1, Cl.LastDateOfWeek)
            AND E.Name = 'incident'
            AND SM.AttributeName = 'statecode'
            AND SM.LangId = 1033
            AND I.CustomerId = C.ContactId
            AND SM.Value = 'Resolved'
    ) ResolvedCases,
    (
        SELECT
            count(*)
        FROM
            CRM.dbo.Incident I
            INNER JOIN CRM.dbo.StringMap SM ON
                I.StateCode = SM.AttributeValue
            INNER JOIN 
                (
                    SELECT
                        DISTINCT ME.Name,
                        ME.ObjectTypeCode
                    FROM
                        CRM.MetadataSchema.Entity ME
                ) E ON
                SM.ObjectTypeCode = E.ObjectTypeCode
        WHERE
            I.ModifiedOn >= Cl.FirstDateOfWeek 
            AND I.ModifiedOn < dateadd(day, 1, Cl.LastDateOfWeek)
            AND E.Name = 'incident'
            AND SM.AttributeName = 'statecode'
            AND SM.LangId = 1033
            AND I.CustomerId = C.ContactId
            AND SM.Value = 'Canceled'
    ) CancelledCases
FROM
    CRM.dbo.Contact C
    CROSS JOIN
        (
            SELECT
                DISTINCT WeekNumber,
                CalendarYear,
                FirstDateOfWeek,
                LastDateOfWeek
            FROM
                Calendar
        ) Cl
ORDER BY
    C.FullName,
    Cl.WeekNumber