我已经获得了以下SQL查询,该查询为我提供了所有超过两年的资产,按组织细分。然后我必须再次运行它,只需删除WHERE
子句中的日期比较部分,找出我的资产总数,这样我就可以给出一个旧的计数,一个总数,然后一个%
有没有办法将所有这些作为单个查询执行?我在查询中可能会考虑某种类型的case
语句吗?
SELECT o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm, COUNT(DISTINCT a.LabAssetSerialNbr) TotalAssets
FROM vw_DimLabAsset a
INNER JOIN vw_DimWorker w ON w.WorkerKey = a.LabAssetAssignedToWorkerKey
INNER JOIN vw_DimOrganizationHierarchy o ON o.OrganizationHierarchyUnitCd = w.WorkerOrganizationUnitCd
AND o.OrganizationHierarchyUnitLevelFourNm IS NOT NULL
WHERE a.SystemCreatedOnDtm < DATEADD(day, DATEDIFF(day, 0, DATEADD(yy, -2, GETDATE())), 0)
AND a.LabAssetTypeNm IN ('u_cmdb_ci_prototype_system', 'u_cmdb_ci_silicon')
AND a.LabAssetHardwareStatus <> 'retired'
AND (a.LabAssetHardwareSubStatus IS NULL OR a.LabAssetHardwareSubStatus <> 'archive')
GROUP BY o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm
ORDER BY 1, 2
我尝试将其添加到选择:`
SUM(CASE WHEN a.SystemCreatedOnDtm < DATEADD(day, DATEDIFF(day, 0, DATEADD(yy, -2, GETDATE())), 0) THEN 1 ELSE 0 END)
但是,它不会返回与TotalAssets值相同的计数。
这是我最终的最终查询:
DECLARE @date DateTime
SELECT @date = DATEADD(day, DATEDIFF(day, 0, DATEADD(yy, -2, GETDATE())), 0);
WITH pphw AS
(
SELECT DISTINCT o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm, a.LabAssetSerialNbr, MIN(a.SystemCreatedOnDtm) MinCreated
FROM vw_DimLabAsset a
INNER JOIN vw_DimWorker w ON a.LabAssetAssignedToWorkerKey = w.WorkerKey
INNER JOIN vw_DimOrganizationHierarchy o ON w.WorkerOrganizationUnitCd = o.OrganizationHierarchyUnitCd
AND o.OrganizationHierarchyUnitLevelThreeNm IS NOT NULL
AND o.OrganizationHierarchyUnitLevelFourNm IS NOT NULL
WHERE LabAssetHardwareStatus <> 'Retired'
AND (LabAssetHardwareSubStatus IS NULL OR LabAssetHardwareSubStatus <> 'Archive')
AND a.LabAssetTypeNm IN ('u_cmdb_ci_prototype_system', 'u_cmdb_ci_silicon')
GROUP BY o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm, a.LabAssetSerialNbr
)
SELECT OrganizationHierarchyUnitLevelThreeNm, OrganizationHierarchyUnitLevelFourNm,
SUM(CASE WHEN MinCreated < @date THEN 1 ELSE 0 END) AssetsOverTwoYears,
COUNT(DISTINCT LabAssetSerialNbr) TotalAssets
FROM pphw
GROUP BY OrganizationHierarchyUnitLevelThreeNm, OrganizationHierarchyUnitLevelFourNm
HAVING SUM(CASE WHEN MinCreated < @date THEN 1 ELSE 0 END) > 0
ORDER BY 1, 2
答案 0 :(得分:1)
我的回答类似于tysonwright,但我认为GROUP BY子句应该在子选择之外。但是,我希望样本数据能够验证这一点。最重要的是,您应首先通过子选择收集您想要计算指标的所有记录。从那里,您可以执行SUMs和COUNTs。
SELECT TMP1.OrganizationHierarchyUnitLevelThreeNm
,TMP1.OrganizationHierarchyUnitLevelFourNm
,TotalAssets = COUNT(TMP1.LabAssetSerialNbr)
,AssetsOver2YearsOld = SUM(TMP1.AssetOver2YearsOldInd)
,PercAssetsOver2YearsOld = SUM(TMP1.AssetOver2YearsOldInd) / COUNT(TMP1.LabAssetSerialNbr)
FROM (SELECT DISTINCT o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm, a.LabAssetSerialNbr
,AssetOver2YearsOldInd = CASE WHEN a.SystemCreatedOnDtm < DATEADD(d, DATEDIFF(d, 0, DATEADD(yy, -2, GETDATE())), 0) THEN 1 ELSE 0 END
FROM vw_DimLabAsset a
INNER JOIN vw_DimWorker w
ON w.WorkerKey = a.LabAssetAssignedToWorkerKey
INNER JOIN vw_DimOrganizationHierarchy o
ON o.OrganizationHierarchyUnitCd = w.WorkerOrganizationUnitCd
AND o.OrganizationHierarchyUnitLevelFourNm IS NOT NULL
WHERE a.LabAssetTypeNm IN ('u_cmdb_ci_prototype_system', 'u_cmdb_ci_silicon')
AND a.LabAssetHardwareStatus <> 'retired'
AND (a.LabAssetHardwareSubStatus IS NULL
OR a.LabAssetHardwareSubStatus <> 'archive')
) TMP1
GROUP BY TMP1.OrganizationHierarchyUnitLevelThreeNm, TMP1.OrganizationHierarchyUnitLevelFourNm
ORDER BY 1, 2
<强>更新强>
要按日期时间删除重复项,您可以使用MIN或MAX功能,具体取决于您的要求:
SELECT TMP1.OrganizationHierarchyUnitLevelThreeNm
,TMP1.OrganizationHierarchyUnitLevelFourNm
,TotalAssets = COUNT(TMP1.LabAssetSerialNbr)
,AssetsOver2YearsOld = SUM(CASE WHEN TMP1.MaxSystemCreatedOnDtm < DATEADD(d, DATEDIFF(d, 0, DATEADD(yy, -2, GETDATE())), 0) THEN 1 ELSE 0 END)
,PercAssetsOver2YearsOld = SUM(CASE WHEN TMP1.MaxSystemCreatedOnDtm < DATEADD(d, DATEDIFF(d, 0, DATEADD(yy, -2, GETDATE())), 0) THEN 1 ELSE 0 END) / COUNT(TMP1.LabAssetSerialNbr)
FROM (SELECT DISTINCT o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm, a.LabAssetSerialNbr, MaxSystemCreatedOnDtm = MAX(a.SystemCreatedOnDtm)
FROM vw_DimLabAsset a
INNER JOIN vw_DimWorker w
ON w.WorkerKey = a.LabAssetAssignedToWorkerKey
INNER JOIN vw_DimOrganizationHierarchy o
ON o.OrganizationHierarchyUnitCd = w.WorkerOrganizationUnitCd
AND o.OrganizationHierarchyUnitLevelFourNm IS NOT NULL
WHERE a.LabAssetTypeNm IN ('u_cmdb_ci_prototype_system', 'u_cmdb_ci_silicon')
AND a.LabAssetHardwareStatus <> 'retired'
AND (a.LabAssetHardwareSubStatus IS NULL
OR a.LabAssetHardwareSubStatus <> 'archive')
GROUP BY o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm, a.LabAssetSerialNbr
) TMP1
GROUP BY TMP1.OrganizationHierarchyUnitLevelThreeNm, TMP1.OrganizationHierarchyUnitLevelFourNm
ORDER BY 1, 2
答案 1 :(得分:0)
我认为这可以满足您的需求:
SELECT
s.OrganizationHierarchyUnitLevelThreeNm,
s.OrganizationHierarchyUnitLevelFourNm,
COUNT(*) TotalAssets,
SUM(CASE WHEN s.SystemCreatedOnDtm < DATEADD(day, DATEDIFF(day, 0, DATEADD(yy, -2, GETDATE())), 0)
THEN 1 ELSE 0 END) AssetsOver2YearsOld,
SUM(CASE WHEN s.SystemCreatedOnDtm < DATEADD(day, DATEDIFF(day, 0, DATEADD(yy, -2, GETDATE())), 0)
THEN 1 ELSE 0 END) / COUNT(*) PercAssetsOver2YearsOld
FROM
(
SELECT
o.OrganizationHierarchyUnitLevelThreeNm,
o.OrganizationHierarchyUnitLevelFourNm
a.LabAssetSerialNbr,
a.SystemCreatedOnDtm
FROM
vw_DimLabAsset a
INNER JOIN
vw_DimWorker w
ON
w.WorkerKey = a.LabAssetAssignedToWorkerKey
INNER JOIN
vw_DimOrganizationHierarchy o
ON
o.OrganizationHierarchyUnitCd = w.WorkerOrganizationUnitCd
AND
o.OrganizationHierarchyUnitLevelFourNm IS NOT NULL
WHERE
a.LabAssetTypeNm IN ('u_cmdb_ci_prototype_system', 'u_cmdb_ci_silicon')
AND
a.LabAssetHardwareStatus <> 'retired'
AND
(a.LabAssetHardwareSubStatus IS NULL OR a.LabAssetHardwareSubStatus <> 'archive')
GROUP BY
o.OrganizationHierarchyUnitLevelThreeNm,
o.OrganizationHierarchyUnitLevelFourNm
a.LabAssetSerialNbr,
a.SystemCreatedOnDtm
) AS s