创建一个对某些数据进行分组但不对其他数据进行分组的视图
Create a view that groups some data, but doesn't group other data
我正在尝试编写一个查询来填充报告。
SQL Fiddle - http://sqlfiddle.com/#!3/920eb
查询依赖于几个不同的表
HardwareSupportRequest
tblCHSRLaborPerCHSR
LaborTypes
tblMaterialUsed
tblMaterial
在 HardwareSupportRequest
中,我有大量的字段,但相关的字段是
CHSRNumber - Basically the ID/unique identifier
Building - Used for grouping by location
WorkType - Can be 'Electric Install','Electric Removal', if it's something else, it'll be ignored and a differ field will be used to group.
tblCHSRLaborPerCHSR
内的字段是
[CHSR#] - fk
[Hours Worked]
[Hourly CHSR Labor Rate]
LaborTypeId
“tblCHSRLabor”内部
id
LaborType
tblMaterialUsed
内部
MaterialId -fk
[CHSR#] - fk
[Amount Used]
'tblMaterial'
内部
id - pk
[Item Cost]
我需要一种生成视图的方法,该视图可以执行一些相当复杂的操作。首先,如果记录的 LaborType 是 Install
、Testing
或 Build
。它们必须被视为单行(用于人工成本)。任何其他 LaborType 都有自己的行。
需要按Building
和LaborType
分组。我还必须计算每条记录有多少个 CHSR。
此时我已经不知所措,正用头撞着键盘。我试过的每一种方法要么失败了,要么让高层摇头。
我最近的尝试:
USE Facilities_Database
DECLARE @minimumDate DATE
DECLARE @maximumDate DATE
SET @minimumDate = '2014/12/11'
SET @maximumDate = '2014/12/15'
SELECT CHSRs.WorkType
,LaborTypes.TypeName AS 'Labor Type'
,CHSRs.Building
,CHSRNumber
,Count(CHSRs.CHSRNumber) AS 'Number of CHSRs'
,ISNULL(SUM(matUsed.cost),0) AS 'Total Material Cost'
,ISNULL(SUM(Labor.[Hour Worked] * Labor.[Hourly CHSR Labor Rate]),0) AS 'Total Labor Cost'
FROM [Facilities].[HardwareSupportRequest] CHSRs
JOIN Facilities.tblCHSRLaborPerCHSR Labor
ON CHSRs.CHSRNumber = Labor.[CHSR #]
JOIN (SELECT ROUND(SUM(matU.[Amount Used] * mat.[Item Cost] * 1.05417 * 1.15),2) AS cost, [CHSR #]
FROM Facilities.tblMaterialUsed matU
JOIN Facilities.tblMaterial mat ON
matU.MaterialId = mat.Id
GROUP BY matU.[CHSR #]) matUsed ON
matUsed.[CHSR #] = CHSRs.CHSRNumber
JOIN Facilities.LaborTypes LaborTypes
ON Labor.LaborTypeId = LaborTypes.Id
WHERE CHSRs.ActualCompleteDate BETWEEN @minimumDate AND @maximumDate AND LaborTypes.TypeName IS NOT NULL
GROUP BY CHSRs.CHSRNumber,CHSRs.WorkType,LaborTypes.TypeName,Building
ORDER BY ChsrNumber,Building,LaborTypes.TypeName
示例 SQL Fiddle - http://sqlfiddle.com/#!3/920eb
编辑
示例输出类似于
Building LaborType NumberOfCHSRs MaterialCost LaborCost
D2 Admin 6 0 300
D2 Install 20 10349.42 32400
D2 Removal 2 350.42 1000
D2 Database 4 0 22000
...
请务必注意,这些材料链接到 CHSR,但它们应该只针对安装和删除进行汇总。
你的测试数据当然很多,但是太窄了。最好只使用几个 CHSR 条目和许多不同的 LaborType,而不是所有 Electric Install。所以我没有做很多测试。但这看起来会让你非常接近你想要的:
select hsr.Building,
case when lt.TypeName in( 'Install', 'Testing', 'Build' )
then 'Labor'
else lt.TypeName end as LaborType,
hsr.CHSRNumber,
Count( * ) as [Number of CHSRs],
Cast( Sum( case when lt.TypeName in( 'Install', 'Removal' )
then mu.[Amount Used] * mat.[Item Cost] * 1.2122955
else 0 end
) as Money )as MaterialCost,
Cast( Sum( lpc.[Hour Worked] * lpc.[Hourly CHSR Labor Rate] )as Money )as LaborCost
from HardwareSupportRequest hsr
join tblCHSRLaborPerCHSR lpc
on lpc.CHSR = hsr.CHSRNumber
join LaborTypes lt
on lt.ID = lpc.LaborTypeID
join tblMaterialUsed mu
on mu.CHSR = hsr.CHSRNumber
join tblMaterial mat
on mat.Id = mu.MaterialId
where hsr.ActualCompleteDate BETWEEN @minimumDate AND @maximumDate
group by hsr.Building,
case when lt.TypeName in( 'Install', 'Testing', 'Build' )
then 'Labor'
else lt.TypeName end,
hsr.CHSRNumber;
您想合并劳动类型为安装、测试和构建的行,所以这就是 case
语句的作用。请注意定义 LaborType 字段的 case
语句和 group by
子句中的语句必须相同。
隐藏在 MaterialCost 字段中的另一个 case
语句允许您仅计算安装和移除成本。不需要强制转换为 Money。我只是把它扔进去炫耀。 ;)
查看 SQL Fiddle。
没有必要对 LaborTypes.TypeName IS NOT NULL
进行测试,因为 NULL 无法通过连接。
我正在尝试编写一个查询来填充报告。
SQL Fiddle - http://sqlfiddle.com/#!3/920eb
查询依赖于几个不同的表
HardwareSupportRequest
tblCHSRLaborPerCHSR
LaborTypes
tblMaterialUsed
tblMaterial
在 HardwareSupportRequest
中,我有大量的字段,但相关的字段是
CHSRNumber - Basically the ID/unique identifier
Building - Used for grouping by location
WorkType - Can be 'Electric Install','Electric Removal', if it's something else, it'll be ignored and a differ field will be used to group.
tblCHSRLaborPerCHSR
内的字段是
[CHSR#] - fk
[Hours Worked]
[Hourly CHSR Labor Rate]
LaborTypeId
“tblCHSRLabor”内部
id
LaborType
tblMaterialUsed
MaterialId -fk
[CHSR#] - fk
[Amount Used]
'tblMaterial'
内部id - pk
[Item Cost]
我需要一种生成视图的方法,该视图可以执行一些相当复杂的操作。首先,如果记录的 LaborType 是 Install
、Testing
或 Build
。它们必须被视为单行(用于人工成本)。任何其他 LaborType 都有自己的行。
需要按Building
和LaborType
分组。我还必须计算每条记录有多少个 CHSR。
此时我已经不知所措,正用头撞着键盘。我试过的每一种方法要么失败了,要么让高层摇头。
我最近的尝试:
USE Facilities_Database
DECLARE @minimumDate DATE
DECLARE @maximumDate DATE
SET @minimumDate = '2014/12/11'
SET @maximumDate = '2014/12/15'
SELECT CHSRs.WorkType
,LaborTypes.TypeName AS 'Labor Type'
,CHSRs.Building
,CHSRNumber
,Count(CHSRs.CHSRNumber) AS 'Number of CHSRs'
,ISNULL(SUM(matUsed.cost),0) AS 'Total Material Cost'
,ISNULL(SUM(Labor.[Hour Worked] * Labor.[Hourly CHSR Labor Rate]),0) AS 'Total Labor Cost'
FROM [Facilities].[HardwareSupportRequest] CHSRs
JOIN Facilities.tblCHSRLaborPerCHSR Labor
ON CHSRs.CHSRNumber = Labor.[CHSR #]
JOIN (SELECT ROUND(SUM(matU.[Amount Used] * mat.[Item Cost] * 1.05417 * 1.15),2) AS cost, [CHSR #]
FROM Facilities.tblMaterialUsed matU
JOIN Facilities.tblMaterial mat ON
matU.MaterialId = mat.Id
GROUP BY matU.[CHSR #]) matUsed ON
matUsed.[CHSR #] = CHSRs.CHSRNumber
JOIN Facilities.LaborTypes LaborTypes
ON Labor.LaborTypeId = LaborTypes.Id
WHERE CHSRs.ActualCompleteDate BETWEEN @minimumDate AND @maximumDate AND LaborTypes.TypeName IS NOT NULL
GROUP BY CHSRs.CHSRNumber,CHSRs.WorkType,LaborTypes.TypeName,Building
ORDER BY ChsrNumber,Building,LaborTypes.TypeName
示例 SQL Fiddle - http://sqlfiddle.com/#!3/920eb
编辑
示例输出类似于
Building LaborType NumberOfCHSRs MaterialCost LaborCost
D2 Admin 6 0 300
D2 Install 20 10349.42 32400
D2 Removal 2 350.42 1000
D2 Database 4 0 22000
...
请务必注意,这些材料链接到 CHSR,但它们应该只针对安装和删除进行汇总。
你的测试数据当然很多,但是太窄了。最好只使用几个 CHSR 条目和许多不同的 LaborType,而不是所有 Electric Install。所以我没有做很多测试。但这看起来会让你非常接近你想要的:
select hsr.Building,
case when lt.TypeName in( 'Install', 'Testing', 'Build' )
then 'Labor'
else lt.TypeName end as LaborType,
hsr.CHSRNumber,
Count( * ) as [Number of CHSRs],
Cast( Sum( case when lt.TypeName in( 'Install', 'Removal' )
then mu.[Amount Used] * mat.[Item Cost] * 1.2122955
else 0 end
) as Money )as MaterialCost,
Cast( Sum( lpc.[Hour Worked] * lpc.[Hourly CHSR Labor Rate] )as Money )as LaborCost
from HardwareSupportRequest hsr
join tblCHSRLaborPerCHSR lpc
on lpc.CHSR = hsr.CHSRNumber
join LaborTypes lt
on lt.ID = lpc.LaborTypeID
join tblMaterialUsed mu
on mu.CHSR = hsr.CHSRNumber
join tblMaterial mat
on mat.Id = mu.MaterialId
where hsr.ActualCompleteDate BETWEEN @minimumDate AND @maximumDate
group by hsr.Building,
case when lt.TypeName in( 'Install', 'Testing', 'Build' )
then 'Labor'
else lt.TypeName end,
hsr.CHSRNumber;
您想合并劳动类型为安装、测试和构建的行,所以这就是 case
语句的作用。请注意定义 LaborType 字段的 case
语句和 group by
子句中的语句必须相同。
隐藏在 MaterialCost 字段中的另一个 case
语句允许您仅计算安装和移除成本。不需要强制转换为 Money。我只是把它扔进去炫耀。 ;)
查看 SQL Fiddle。
没有必要对 LaborTypes.TypeName IS NOT NULL
进行测试,因为 NULL 无法通过连接。