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

时间:2015-02-10 21:07:34

标签: sql sql-server tsql common-table-expression

我正在尝试编写一个查询来填充报告。

SQL小提琴 - 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小提琴 - 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相关联,但它们只能用于安装和删除。

1 个答案:

答案 0 :(得分:1)

你当然有很多测试数据,但它太窄了。最好只使用几个CHSR条目和许多不同的LaborTypes而不是所有 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语句允许您仅计算安装和删除成本。投入金钱是没有必要的。我只是把它扔进去炫耀。 ;)

查看 SQL Fiddle

LaborTypes.TypeName IS NOT NULL的测试不是必需的,因为NULL不会通过连接。