创建一个对某些数据进行分组但不对其他数据进行分组的视图

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 是 InstallTestingBuild。它们必须被视为单行(用于人工成本)。任何其他 LaborType 都有自己的行。

需要按BuildingLaborType分组。我还必须计算每条记录有多少个 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 无法通过连接。