更好的写法 sql - CTE/Temp table
Better way to write this sql - CTE/Temp table
我真的需要一些帮助才能更有效地编写这段代码。我基本上是在创建一个 CTE 来保存包含车辆的数据集,按天和它们装载的容器的重量。容器需要有一定的重量,因此 pass/fail 字段。
我想做的就是获取 CTE 中的提升级别详细信息,并将其聚合为具有 pass/fail 标准的提升容器的数量,并汇总任何失败提升的原因。
我只是想知道最好的方法是使用 CTE,还是 temp table 或任何方法会加快速度或更标准的做法?
理想情况下,我会 post CTE 数据的图像,然后是输出数据,但我不能 post 图像:(
非常感谢
WITH DetailLifts
AS (SELECT CO.Description 'Outlet',
LE.[VehicleCode],
S.FORENAME + ' ' + S.SURNAME AS Name,
le.[CollectionDate],
le.lifteventid,
C.CustomerName,
Cast([CollectionTimeStamp] AS TIME) 'CollectionTime',
LE.[NetWeight],
le.grossweight,
le.tareweight,
ct.description,
CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END 'Threshold',
CASE
WHEN le.Grossweight IS NOT NULL
AND le.grossweight - le.tareweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.grossweight - le.tareweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN le.grossweight IS NULL
AND le.netweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.netweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN le.netweight IS NULL THEN 0
WHEN le.grossweight = 0
AND le.tareweight = 0
AND le.netweight = 0 THEN 0
ELSE 0
END 'Overweight',
CASE
WHEN Isnull([LiftText], 'No') = 'No' THEN 1
ELSE 0
END AS 'NoLift',
CASE
WHEN Isnull([LiftText], 'No') = 'no' THEN 0
ELSE 1
END AS 'Lifts',
CASE
WHEN SOI.SiteOrderId IS NULL THEN 'Not Matched'
ELSE 'Matched'
END AS 'MatchedLogic',
CASE
WHEN Isnull([LiftText], 'No') = 'No'
AND LiftInformationId IS NOT NULL THEN 'Yes'
ELSE 'No'
END 'Reason Code Used',
r2.Description AS 'ReasonCode',
CASE
WHEN le.Grossweight IS NOT NULL
AND le.grossweight - le.tareweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.grossweight - le.tareweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 0
WHEN le.grossweight IS NULL
AND le.netweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.netweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 0
WHEN ( Substring(le.vehiclecode, 3, 2) IN ( 57, 58, 63, 14,
64, 15, 65 )
OR ct.description LIKE '%fel%' )
AND le.netweight IS NOT NULL
AND le.grossweight IS NULL THEN 0
WHEN le.netweight IS NULL
OR ( le.grossweight = 0
AND le.tareweight = 0 ) THEN 0
ELSE 1
END 'Pass',
CASE
WHEN le.Grossweight IS NOT NULL
AND le.grossweight - le.tareweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.grossweight - le.tareweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN le.grossweight IS NULL
AND le.netweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.netweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN ( Substring(le.vehiclecode, 3, 2) IN ( 57, 58, 63, 14,
64, 15, 65 )
OR ct.description LIKE '%fel%' )
AND le.netweight IS NOT NULL
AND le.grossweight IS NULL THEN 1
WHEN le.netweight IS NULL
OR ( le.grossweight = 0
AND le.tareweight = 0 ) THEN 1
ELSE 0
END 'Fail',
lifttext,
CASE
WHEN ( Substring(le.vehiclecode, 3, 2) IN ( 57, 58, 63, 14,
64, 15, 65 )
OR ct.description LIKE '%fel%' )
AND le.netweight IS NOT NULL
AND le.grossweight IS NULL THEN 1
ELSE 0
END AS 'VehicleFault'
FROM [CFO_P155_Pre_Production_ELEMOS].[dbo].[LiftEvent]LE
LEFT JOIN CFO_P155_Pre_Production_ELEMOS.dbo.Route RT
ON RT.routeid = le.routeid
LEFT JOIN CFO_P155_Pre_Production_ELEMOS.dbo.SysUser S
ON S.sysuserid = RT.driversysuserid
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Vehicle]V
ON LE.VehicleId = V.VehicleId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[CompanyOutlet]CO
ON V.CompanyOutletId = CO.CompanyOutletId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Reason]R
ON LE.LiftProblemId = R.ReasonId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Reason]R2
ON LE.LiftInformationId = R2.ReasonId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[SiteOrderItem]SOI
ON SOI.SiteOrderItemId = LE.SiteOrderItemId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[SiteOrder]SO
ON SOI.SiteOrderId = SO.SiteOrderId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[CustomerSite]CS
ON SO.CustomerSiteId = CS.CustomerSiteId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Location]L
ON CS.LocationId = L.LocationId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Customer]C
ON CS.CustomerId = C.CustomerId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Material]M
ON SO.MaterialId = M.Materialid
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[ContainerType]CT
ON SOI.ContainerTypeId = CT.ContainerTypeId
WHERE CO.Description IN ( 'Portsmouth' )
AND le.CollectionDate >= '2015-03-02'
AND le.CollectionDate <= '2015-03-06'
AND ( ct.description LIKE '%euro%'
OR ct.description LIKE '%FEl%' )
--and substring(le.vehiclecode,3,2) in (57,58,63,64,65) and le.netweight is not null and le.grossweight is null
AND C.Customerid = 18407)
SELECT dl.outlet,
dl.collectiondate,
dl.vehiclecode,
dl.name,
CASE
WHEN passesandfails.Pass >= 5
AND passesandfails.Fail = 0 THEN 'Pass'
ELSE 'Fail'
END AS 'Pass or Fail',
passesandfails.pass,
passesandfails.fail,
Isnull(matchedlifts.matchedActuallifts, 0) AS MatchedActualLifts,
Isnull(lifted.NoLift, 0) AS 'MatchedNotLifted(Lift Complete)',
Isnull(overweights.overweight, 0) AS Overweights,
Sum(vehiclefault) AS VehicleFault
FROM DetailLifts DL
LEFT JOIN (SELECT outlet,
collectiondate,
vehiclecode,
Sum(pass) pass,
Sum(fail) fail
FROM detaillifts dl
GROUP BY outlet,
collectiondate,
vehiclecode) AS PassesandFails
ON dl.Collectiondate = passesandfails.collectiondate
AND dl.vehiclecode = passesandfails.vehiclecode
LEFT JOIN (SELECT outlet,
collectiondate,
vehiclecode,
Sum(overweight)AS overweight
FROM detaillifts DL
GROUP BY outlet,
collectiondate,
vehiclecode) AS Overweights
ON dl.collectiondate = overweights.collectiondate
AND dl.vehiclecode = overweights.vehiclecode
LEFT JOIN (SELECT collectiondate,
vehiclecode,
Count(lifteventid) AS MatchedActualLifts
FROM detaillifts DL
WHERE lifttext IS NOT NULL
GROUP BY collectiondate,
vehiclecode) AS MatchedLifts
ON dl.collectiondate = matchedlifts.collectiondate
AND dl.vehiclecode = matchedlifts.vehiclecode
LEFT JOIN (SELECT collectiondate,
vehiclecode,
Sum(lifts) AS Lifts,
Sum(nolift) AS NoLift
FROM detaillifts
GROUP BY collectiondate,
vehiclecode)AS lifted
ON lifted.collectiondate = dl.collectiondate
AND lifted.vehiclecode = dl.vehiclecode
GROUP BY dl.outlet,
dl.collectiondate,
dl.vehiclecode,
dl.name,
matchedActuallifts,
passesandfails.pass,
passesandfails.fail,
lifted.nolift,
overweights.overweight
ORDER BY outlet,
collectiondate,
vehiclecode
CTE 只是语法并被评估
但是如果 CTE 运行 很快就不是问题
物化到 t #temp
是有代价的
运行 仅 CTE 需要多长时间?
整个查询需要多长时间?
但是您有两个不需要的联接
将 Sum(overweight)AS overweight 上移到 PassesandFails
将 Count(lifteventid) 向下移动到 lifted as Count(lifttext)
null 不计入
这将使连接开销减少 1/2
如果您得到了您期望的答案,那么我认为发布数据没有任何意义
我真的需要一些帮助才能更有效地编写这段代码。我基本上是在创建一个 CTE 来保存包含车辆的数据集,按天和它们装载的容器的重量。容器需要有一定的重量,因此 pass/fail 字段。
我想做的就是获取 CTE 中的提升级别详细信息,并将其聚合为具有 pass/fail 标准的提升容器的数量,并汇总任何失败提升的原因。
我只是想知道最好的方法是使用 CTE,还是 temp table 或任何方法会加快速度或更标准的做法?
理想情况下,我会 post CTE 数据的图像,然后是输出数据,但我不能 post 图像:(
非常感谢
WITH DetailLifts
AS (SELECT CO.Description 'Outlet',
LE.[VehicleCode],
S.FORENAME + ' ' + S.SURNAME AS Name,
le.[CollectionDate],
le.lifteventid,
C.CustomerName,
Cast([CollectionTimeStamp] AS TIME) 'CollectionTime',
LE.[NetWeight],
le.grossweight,
le.tareweight,
ct.description,
CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END 'Threshold',
CASE
WHEN le.Grossweight IS NOT NULL
AND le.grossweight - le.tareweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.grossweight - le.tareweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN le.grossweight IS NULL
AND le.netweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.netweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN le.netweight IS NULL THEN 0
WHEN le.grossweight = 0
AND le.tareweight = 0
AND le.netweight = 0 THEN 0
ELSE 0
END 'Overweight',
CASE
WHEN Isnull([LiftText], 'No') = 'No' THEN 1
ELSE 0
END AS 'NoLift',
CASE
WHEN Isnull([LiftText], 'No') = 'no' THEN 0
ELSE 1
END AS 'Lifts',
CASE
WHEN SOI.SiteOrderId IS NULL THEN 'Not Matched'
ELSE 'Matched'
END AS 'MatchedLogic',
CASE
WHEN Isnull([LiftText], 'No') = 'No'
AND LiftInformationId IS NOT NULL THEN 'Yes'
ELSE 'No'
END 'Reason Code Used',
r2.Description AS 'ReasonCode',
CASE
WHEN le.Grossweight IS NOT NULL
AND le.grossweight - le.tareweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.grossweight - le.tareweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 0
WHEN le.grossweight IS NULL
AND le.netweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.netweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 0
WHEN ( Substring(le.vehiclecode, 3, 2) IN ( 57, 58, 63, 14,
64, 15, 65 )
OR ct.description LIKE '%fel%' )
AND le.netweight IS NOT NULL
AND le.grossweight IS NULL THEN 0
WHEN le.netweight IS NULL
OR ( le.grossweight = 0
AND le.tareweight = 0 ) THEN 0
ELSE 1
END 'Pass',
CASE
WHEN le.Grossweight IS NOT NULL
AND le.grossweight - le.tareweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.grossweight - le.tareweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN le.grossweight IS NULL
AND le.netweight < ( CASE
WHEN CT.Description LIKE 'Euro%' THEN -10
WHEN CT.Description LIKE 'FEL%' THEN -30
END )
OR le.netweight > ( CASE
WHEN CT.Description LIKE 'Euro%' THEN 10
WHEN CT.Description LIKE 'FEL%' THEN 30
END ) THEN 1
WHEN ( Substring(le.vehiclecode, 3, 2) IN ( 57, 58, 63, 14,
64, 15, 65 )
OR ct.description LIKE '%fel%' )
AND le.netweight IS NOT NULL
AND le.grossweight IS NULL THEN 1
WHEN le.netweight IS NULL
OR ( le.grossweight = 0
AND le.tareweight = 0 ) THEN 1
ELSE 0
END 'Fail',
lifttext,
CASE
WHEN ( Substring(le.vehiclecode, 3, 2) IN ( 57, 58, 63, 14,
64, 15, 65 )
OR ct.description LIKE '%fel%' )
AND le.netweight IS NOT NULL
AND le.grossweight IS NULL THEN 1
ELSE 0
END AS 'VehicleFault'
FROM [CFO_P155_Pre_Production_ELEMOS].[dbo].[LiftEvent]LE
LEFT JOIN CFO_P155_Pre_Production_ELEMOS.dbo.Route RT
ON RT.routeid = le.routeid
LEFT JOIN CFO_P155_Pre_Production_ELEMOS.dbo.SysUser S
ON S.sysuserid = RT.driversysuserid
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Vehicle]V
ON LE.VehicleId = V.VehicleId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[CompanyOutlet]CO
ON V.CompanyOutletId = CO.CompanyOutletId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Reason]R
ON LE.LiftProblemId = R.ReasonId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Reason]R2
ON LE.LiftInformationId = R2.ReasonId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[SiteOrderItem]SOI
ON SOI.SiteOrderItemId = LE.SiteOrderItemId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[SiteOrder]SO
ON SOI.SiteOrderId = SO.SiteOrderId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[CustomerSite]CS
ON SO.CustomerSiteId = CS.CustomerSiteId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Location]L
ON CS.LocationId = L.LocationId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Customer]C
ON CS.CustomerId = C.CustomerId
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[Material]M
ON SO.MaterialId = M.Materialid
LEFT JOIN [CFO_P155_Pre_Production_ELEMOS].[dbo].[ContainerType]CT
ON SOI.ContainerTypeId = CT.ContainerTypeId
WHERE CO.Description IN ( 'Portsmouth' )
AND le.CollectionDate >= '2015-03-02'
AND le.CollectionDate <= '2015-03-06'
AND ( ct.description LIKE '%euro%'
OR ct.description LIKE '%FEl%' )
--and substring(le.vehiclecode,3,2) in (57,58,63,64,65) and le.netweight is not null and le.grossweight is null
AND C.Customerid = 18407)
SELECT dl.outlet,
dl.collectiondate,
dl.vehiclecode,
dl.name,
CASE
WHEN passesandfails.Pass >= 5
AND passesandfails.Fail = 0 THEN 'Pass'
ELSE 'Fail'
END AS 'Pass or Fail',
passesandfails.pass,
passesandfails.fail,
Isnull(matchedlifts.matchedActuallifts, 0) AS MatchedActualLifts,
Isnull(lifted.NoLift, 0) AS 'MatchedNotLifted(Lift Complete)',
Isnull(overweights.overweight, 0) AS Overweights,
Sum(vehiclefault) AS VehicleFault
FROM DetailLifts DL
LEFT JOIN (SELECT outlet,
collectiondate,
vehiclecode,
Sum(pass) pass,
Sum(fail) fail
FROM detaillifts dl
GROUP BY outlet,
collectiondate,
vehiclecode) AS PassesandFails
ON dl.Collectiondate = passesandfails.collectiondate
AND dl.vehiclecode = passesandfails.vehiclecode
LEFT JOIN (SELECT outlet,
collectiondate,
vehiclecode,
Sum(overweight)AS overweight
FROM detaillifts DL
GROUP BY outlet,
collectiondate,
vehiclecode) AS Overweights
ON dl.collectiondate = overweights.collectiondate
AND dl.vehiclecode = overweights.vehiclecode
LEFT JOIN (SELECT collectiondate,
vehiclecode,
Count(lifteventid) AS MatchedActualLifts
FROM detaillifts DL
WHERE lifttext IS NOT NULL
GROUP BY collectiondate,
vehiclecode) AS MatchedLifts
ON dl.collectiondate = matchedlifts.collectiondate
AND dl.vehiclecode = matchedlifts.vehiclecode
LEFT JOIN (SELECT collectiondate,
vehiclecode,
Sum(lifts) AS Lifts,
Sum(nolift) AS NoLift
FROM detaillifts
GROUP BY collectiondate,
vehiclecode)AS lifted
ON lifted.collectiondate = dl.collectiondate
AND lifted.vehiclecode = dl.vehiclecode
GROUP BY dl.outlet,
dl.collectiondate,
dl.vehiclecode,
dl.name,
matchedActuallifts,
passesandfails.pass,
passesandfails.fail,
lifted.nolift,
overweights.overweight
ORDER BY outlet,
collectiondate,
vehiclecode
CTE 只是语法并被评估
但是如果 CTE 运行 很快就不是问题
物化到 t #temp
是有代价的
运行 仅 CTE 需要多长时间?
整个查询需要多长时间?
但是您有两个不需要的联接
将 Sum(overweight)AS overweight 上移到 PassesandFails
将 Count(lifteventid) 向下移动到 lifted as Count(lifttext)
null 不计入
这将使连接开销减少 1/2
如果您得到了您期望的答案,那么我认为发布数据没有任何意义