内部报告需要复杂的小计

发布于 2024-08-18 11:33:47 字数 2399 浏览 6 评论 0原文

我需要一个按 MemberName(PersonID) 返回小计的查询,但又分为 2 个不同的 ContactTypes11 和 12 下IsFaceToFace)。下面的查询为我提供了我需要的基本数据,没有任何小计。

我尝试使用 WITH ROLLUPPARTITION BY 但这些对我来说是新的,从来没有完全正确地工作过。我确信我需要提供有关表结构的更多信息,但也许不需要。

另外,我的最终目标是在 Excel 2007 中为我们的内部财务团队提供此功能,因此我对任何解决方案持非常开放的态度。无论是 SQL、LINQ(尽管这使用 2 个 db)、Reporting Services、Excel 宏、C# 等。此时我只需要它能够工作。

我最好的选择是什么? 这是当前返回的示例。

ClientFolder MemberName        ContactDate  TimeSpent IsFaceToFace

68933   Collins,Vickie          2010-01-07  0.2    11
68937   Pervin,Jennifer         2010-01-07  0.2    11
68937   Pervin,Jennifer         2010-01-11  0.1    11
68937   Pervin,Jennifer         2010-01-12  0.1    11
69861   Klum,Ronald             2010-01-04  0.3    11
69861   Klum,Ronald             2010-01-04  0.3    11
69861   Klum,Ronald             2010-01-07  0.2    11
69861   Klum,Ronald             2010-01-11  0.2    11
70205   Matamoros,Joellen       2010-01-04  0.5    11
70205   Matamoros,Joellen       2010-01-06  0.8    11
70205   Matamoros,Joellen       2010-01-06  2.4    12
70205   Matamoros,Joellen       2010-01-07  0.7    11
70205   Matamoros,Joellen       2010-01-11  0.2    11
70205   Matamoros,Joellen       2010-01-11  1.0    11
70205   Matamoros,Joellen       2010-01-12  0.3    11



USE MATRIX

SELECT  ClientFolder = (select distinct tblApplicationAssociation.PersonApplicationID from Connect.dbo.tblApplicationAssociation where Connect.dbo.tblApplicationAssociation.ApplicationID = 6 AND Connect.dbo.tblApplicationAssociation.PersonID = MATRIX.dbo.tblCaseNotes.PersonID)
        ,MemberName = (select tblPerson.LastName + ',' + tblPerson.FirstName from Connect.dbo.tblPerson where Connect.dbo.tblPerson.PersonID = MATRIX.dbo.tblCaseNotes.PersonID)
        ,ContactDate
        ,TimeSpent = SUM(TimeSpentUnits)
        ,CASE WHEN ContactTypeID = 3 THEN '12' ELSE '11' END AS IsFaceToFace

FROM tblCaseNotes
        LEFT OUTER JOIN tblCaseNoteContactType
                ON tblCaseNotes.CaseNoteID = tblCaseNoteContactType.CaseNoteID

WHERE InsertUser = 'pschaller' -- this will be a variable for Current User
AND 
ContactDate BETWEEN '01/01/2010' AND '01/31/2010' -- this will be two Date variables

GROUP BY ContactDate, ContactTypeID, PersonID
ORDER BY PersonID, ContactDate, ContactTypeID

I need a query that returns subtotals by MemberName(PersonID) but broke out into the 2 different ContactTypes(11 & 12 under IsFaceToFace). The below query gets me the base data I need without any subtotals.

I tried messing around with WITH ROLLUP and PARTITION BY but those are new to me and never worked completely right. I am sure I will need to provide more info on table structure but maybe not.

Also, my ultimate goal is to provide this in Excel 2007 for our in house Finance team so I am very open to ANY solution. Be it SQL, LINQ(though this uses 2 db's), Reporting Services, Excel Macro, C#, etc. I just need it to work at this point.

What are my best options?
This is a sample of what is currently returned.

ClientFolder MemberName        ContactDate  TimeSpent IsFaceToFace

68933   Collins,Vickie          2010-01-07  0.2    11
68937   Pervin,Jennifer         2010-01-07  0.2    11
68937   Pervin,Jennifer         2010-01-11  0.1    11
68937   Pervin,Jennifer         2010-01-12  0.1    11
69861   Klum,Ronald             2010-01-04  0.3    11
69861   Klum,Ronald             2010-01-04  0.3    11
69861   Klum,Ronald             2010-01-07  0.2    11
69861   Klum,Ronald             2010-01-11  0.2    11
70205   Matamoros,Joellen       2010-01-04  0.5    11
70205   Matamoros,Joellen       2010-01-06  0.8    11
70205   Matamoros,Joellen       2010-01-06  2.4    12
70205   Matamoros,Joellen       2010-01-07  0.7    11
70205   Matamoros,Joellen       2010-01-11  0.2    11
70205   Matamoros,Joellen       2010-01-11  1.0    11
70205   Matamoros,Joellen       2010-01-12  0.3    11



USE MATRIX

SELECT  ClientFolder = (select distinct tblApplicationAssociation.PersonApplicationID from Connect.dbo.tblApplicationAssociation where Connect.dbo.tblApplicationAssociation.ApplicationID = 6 AND Connect.dbo.tblApplicationAssociation.PersonID = MATRIX.dbo.tblCaseNotes.PersonID)
        ,MemberName = (select tblPerson.LastName + ',' + tblPerson.FirstName from Connect.dbo.tblPerson where Connect.dbo.tblPerson.PersonID = MATRIX.dbo.tblCaseNotes.PersonID)
        ,ContactDate
        ,TimeSpent = SUM(TimeSpentUnits)
        ,CASE WHEN ContactTypeID = 3 THEN '12' ELSE '11' END AS IsFaceToFace

FROM tblCaseNotes
        LEFT OUTER JOIN tblCaseNoteContactType
                ON tblCaseNotes.CaseNoteID = tblCaseNoteContactType.CaseNoteID

WHERE InsertUser = 'pschaller' -- this will be a variable for Current User
AND 
ContactDate BETWEEN '01/01/2010' AND '01/31/2010' -- this will be two Date variables

GROUP BY ContactDate, ContactTypeID, PersonID
ORDER BY PersonID, ContactDate, ContactTypeID

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光匆匆的小流年 2024-08-25 11:33:47

如果你想将其保留在 SQL 中,你确实有 2 个选择,我认为这将是最快的方法。您可以使用 PARTITION BY,也可以将查询结果插入到临时表中,然后再次查询它们。使用 Partition By 的真正作用就是将所需的 SQL 语句数量从 2 个减少到 1 个,并删除临时表。要使用临时表,只需将上述查询的结果插入其中,然后从中执行 SELECT 操作并按 PersonID 和 IsFaceToFace 进行分组。

You really have 2 options if you want keep it in SQL, which I think will be the quickest way to do it. You can either use PARTITION BY or you can insert your Query results into a temp table and then query them a second time. All using Partition By really does is reduce the number of SQL statements you need to have from 2 to 1 and remove the temp table. To use the temp table just insert the result of your above query into it and then do a SELECT from it and group by PersonID and IsFaceToFace.

爱殇璃 2024-08-25 11:33:47

通常,我建议使用直接聚合函数,但是您需要进行一些复杂的联接,并且我不知道哪些字段属于哪个表。

我就是这样做的。

创建一个临时表:-

DECLARE @contacts TABLE
(
     ClientFolder int
    ,MemberName   varchar(256)
    ,ContactDate  datetime
    ,TimeSpent    decimal(10,1)
    ,IsFaceToFace int
)


INSERT INTO @contacts
(
     ClientFolder
    ,MemberName
    ,ContactDate
    ,TimeSpent
    ,IsFaceToFace
)
-- Your select statement

然后,

SELECT 
     MemberName
    ,IsFaceToFace
    ,SUM(TimeSpent) AS TimeSpent
    ,MAX(ContactDate) AS ContactDate
FROM
    @contacts
GROUP BY
    MemberName,
    IsFaceToFace

它的速度很快,但需要临时表开销,并且如果需要,您可以再次使用该表。

至于报告,您可以使用 Microsoft SQL Server Reporting Services(如果可用)。某些版本存在问题,但它确实具有 Excel 导出功能,对于这种简单的输出来说应该很好。

它还受益于订阅功能,您可以安排定时运行的报告以通过邮件或放置在文件共享中的方式交付给用户。

Normally, I'd suggest a straight aggregate function, but you've got some complex joins going on and I don't know which fields belong to which table.

This is how I'd do it.

Create a temp table :-

DECLARE @contacts TABLE
(
     ClientFolder int
    ,MemberName   varchar(256)
    ,ContactDate  datetime
    ,TimeSpent    decimal(10,1)
    ,IsFaceToFace int
)


INSERT INTO @contacts
(
     ClientFolder
    ,MemberName
    ,ContactDate
    ,TimeSpent
    ,IsFaceToFace
)
-- Your select statement

Then,

SELECT 
     MemberName
    ,IsFaceToFace
    ,SUM(TimeSpent) AS TimeSpent
    ,MAX(ContactDate) AS ContactDate
FROM
    @contacts
GROUP BY
    MemberName,
    IsFaceToFace

It's fast at the cost of a temp table overhead, and you can use the table again if you need to.

As for reporting, you could employ Microsoft SQL Server Reporting Services, if available. Some versions have their problems, but it does have an Excel export facility that should be fine for output of this simplicity.

It also benefits from a subscription facility, whereby you can arrange timed runs of the report to be delivered to users, either by mail or placed in a file share.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文