SQL Server 详细查询(包含总计和总计)

标签 sql sql-server-2005 group-by calculated-columns

我正在尝试生成一个 SQL 查询结果集,该结果集将允许我重现详细的计费报告,其中包含按位置划分的总计,以及最后所有位置的总计。 (我们正在从 Crystal Reports 移植)

不幸的是,细节是在许多连接在一起的表格中,并且它并不像我找到的示例那么简单。

这是我想要的数据输出:

ID  LastName  FirstName  Location  TestDateTime  ReaderLastName    ReaderFirstName   FeeCharged
1   Test      Mary       MyTown    12/01/2014    Smith             Tom              10
2   Test      John       MyTown    12/02/2014    Smith             Tom              10
                         MyTown                                                     20
3   Testing   Andy       YourTown  12/12/2014    Cabin             Fred             15
4   Jones     Lou        YourTown  12/13/2014    Cabin             Fred             15
5   Sun       Mike       YourTown  12/15/2014    Boat              Karen            15
                         YourTown                                                   45
                         All                                                        65

这是我到目前为止所做的,即获取我正在寻找的两个单独的部分...首先是详细部分,按位置求和:

SELECT
    tpd.ID, 
    tpd.LastName,
    tpd.FirstName,
    cl.Location, 
    ttd.TestDateTime, 
    ttd.ReaderLastName, 
    ttd.ReaderFirstName,
    cld.FeeCharged 
FROM   ((tstTestDemographics ttd 
INNER JOIN cfgLocationsDispatches cld 
ON ttd.Location=cld.LocationID) 
INNER JOIN tstPatientDemographics tpd 
ON ttd.TestID=tpd.TestID) 
INNER JOIN cfgLocations cl
ON cld.LocationID=cl.LocationID
WHERE  ttd.TestStatus=1 AND tpd.TestID>0 
AND cld.FeeCharged<>0 
AND (ttd.TestDateTime>={ts '2014-11-01 00:00:00'} 
AND ttd.TestDateTime<{ts '2014-12-01 00:00:00'})
ORDER BY cl.Location, ttd.TestDateTime
COMPUTE SUM(cld.FeeCharged)  BY cl.Location

但是,这会产生多个集合,而我宁愿拥有一个大集合。

这是迄今为止我仅对小计和总计进行的查询:

SELECT 
    CASE WHEN (Grouping(cl.Location) = 1) THEN 'Grand Total for Month'
    ELSE ISNULL(cl.Location, 'UNKNOWN')
    END as LocationName, 
    SUM(cld.FeeCharged) as 'FeeCharged Total'
FROM   ((tstTestDemographics ttd 
INNER JOIN cfgLocationsDispatches cld 
ON ttd.Location=cld.LocationID) 
INNER JOIN tstPatientDemographics tpd 
ON ttd.TestID=tpd.TestID) 
INNER JOIN cfgLocations cl
ON cld.LocationID=cl.LocationID
WHERE  ttd.TestStatus=1 AND tpd.TestID>0 
AND cld.FeeCharged<>0 
AND (ttd.TestDateTime>={ts '2014-11-01 00:00:00'} 
AND ttd.TestDateTime<{ts '2014-12-01 00:00:00'})
GROUP BY cl.Location WITH ROLLUP

有什么方法可以在一个大查询中获取详细列表以及小计和总计吗?

我的分组尝试给了我很多我并不真正想要的重复项和空值。 我是汇总和分组功能的新手。我认为我的数据库是 SQL Server 2005,因为某些高级 2008 分组语法不起作用。

最佳答案

您希望将收费相加。使用分组集,基本上在第一个查询上:

SELECT tpd.ID, tpd.LastName, tpd.FirstName,
       (CASE WHEN (Grouping(cl.Location) = 1) THEN 'ALL' ELSE cl.Location END) as location,
       ttd.TestDateTime,
       ttd.ReaderLastName, ttd.ReaderFirstName,
       SUM(cld.FeeCharged) as FeeCharged
FROM tstTestDemographics ttd INNER JOIN
     cfgLocationsDispatches cld 
     ON ttd.Location=cld.LocationID INNER JOIN
     tstPatientDemographics tpd ON
     ttd.TestID = tpd.TestID INNER JOIN
     cfgLocations cl
     ON cld.LocationID = cl.LocationID
WHERE ttd.TestStatus = 1 AND tpd.TestID > 0 AND
      cld.FeeCharged <> 0 AND
      (ttd.TestDateTime>={ts '2014-11-01 00:00:00'} AND
       ttd.TestDateTime<{ts '2014-12-01 00:00:00'}) 
GROUP BY GROUPING SETS((tpd.ID, tpd.LastName, tpd.FirstName, cl.Location, ttd.TestDateTime, ttd.ReaderLastName, ttd.ReaderFirstName),
                       (cl.location)
                      ) 
ORDER BY cl.Location, ttd.TestDateTime

编辑:

在 SQL Server 2005 中,您可以使用联合来完成此操作。我将大部分逻辑放在 CTE 中,因此重复它很容易。查询看起来像这样:

WITH CTE as (
      SELECT tpd.ID, tpd.LastName, tpd.FirstName, cl.Location,
             ttd.TestDateTime, ttd.ReaderLastName, ttd.ReaderFirstName, cld.FeeCharged
      FROM tstTestDemographics ttd INNER JOIN
           cfgLocationsDispatches cld 
           ON ttd.Location=cld.LocationID INNER JOIN
           tstPatientDemographics tpd ON
           ttd.TestID = tpd.TestID INNER JOIN
           cfgLocations cl
           ON cld.LocationID = cl.LocationID
      WHERE ttd.TestStatus = 1 AND tpd.TestID > 0 AND
            cld.FeeCharged <> 0 AND
            (ttd.TestDateTime>={ts '2014-11-01 00:00:00'} AND
             ttd.TestDateTime<{ts '2014-12-01 00:00:00'}) 
     )
SELECT t.*
FROM ((select id, lastname, firtstname, location, testdatetime, readerlastname, readerfirstname,
              sum(feecharged) as feecharged
       from cte
       group by id, lastname, firtstname, location, testdatetime, readerlastname, readerfirstname
      ) union all
      (select NULL, NULL, NULL, location, NULL, NULL, NULL,
              sum(feecharged) as feecharged
       from cte
       group by location
      )
     ) t
ORDER BY location, (case when id is null then 2 else 1 end);

关于SQL Server 详细查询(包含总计和总计),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27641977/

相关文章:

MySQL View - 来自多个表的计算列返回 NULL

c# - 如何检查 List<Model> 中的重复项

php - 论坛 - 按上次事件在多个页面上排序的主题

sql - 高级 SQL GROUP BY 查询

t-sql - 使用交叉连接更新查询

python - 在 pandas dataframe 的组内添加 timedelta 数据

sql - 如果整个列中的值为空,则从输出中删除

MySQL:M:N 关系的子集和超集

java - MSSQL - Java/JTDS 和 Join 的列名称无效

sql-server - 重新编译存储过程?