我正在尝试生成一个 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/