【问题标题】:SQL Query in CRM ReportCRM 报表中的 SQL 查询
【发布时间】:2012-10-27 18:13:03
【问题描述】:

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

我正在尝试 在 CRM 中构建一个报告,用一年中的每一周(每一行是不同的一周)填充表格,然后计算具有每个状态选项的案例数量(列将是每个状态选项)。

表格应该是这样的

         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 行,并按日期过滤这些结果(联系人表中的列)。我对 SQL 查询和 CRM 有点陌生 - 这里的任何帮助将不胜感激。

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

【问题讨论】:

  • 如果你已经有所有 52 行的数据,那么试试这个。您需要选择每个状态并将其添加到您的 group by 子句中。 select status1, status2, status3, count(*) from contact group by status1, status2, status3 order by week.
  • 谢谢zundarz。我实际上没有所有行中的数据,我现在只有一行这样:状态 1 |状态 2 |状态 3 12 | 33 | 21 现在我想弄清楚如何将其分成 52 行,每行代表一年中不同的一周。
  • 啊,我明白了。此外,我给你的查询不会给你你想要的 3 个计数。它只会为您提供所有三个 status1、status2、status3 组合的计数..

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


【解决方案1】:

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

由于您似乎还想要无限范围的日期,所以 marc_s 有一个很好的总结,说明了如何以通用方式使用日期进行分组:SQL group by frequency within a date range

【讨论】:

    【解决方案2】:

    所以,让我们分解一下:

    您想要制作一份报告,按周为每个联系人显示该联系人注册的案例数量的明细,该明细分为三列,每个 StateCode 列。

    如果是这种情况,那么您需要为每个联系人提供 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
    

    【讨论】:

    • +1 在这种情况下,我比 Marc 更喜欢您的解决方案,并且您在问题的上下文中详细说明了您的答案。不错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多