我有两个具有不同整体结构的表,但是它们共享3个列名:
dbo.[Moves]
Id | DeviceId | TL_Event_Date | ...
---|------------|--------------------------|------
1 | D810 | 2020-01-28 09:19:55.587 | ...
2 | D810 | 2020-01-29 09:19:55.587 | ...
3 | D710 | 2020-01-29 09:19:55.587 | ...
4 | D812 | 2020-01-29 09:19:55.587 | ...
...
dbo.[Faults]
Id | DeviceId | TL_Event_Date | ...
---|------------|--------------------------|------
1 | D610 | timestamp | ...
2 | D810 | timestamp | ...
3 | D710 | timestamp | ...
4 | D812 | timestamp | ...
...
两个表都有更多列,但是只需要DeviceId和TL_Event_Date来填写查询的WHERE子句。
我想获得给定时间范围内特定DeviceId的移动和故障数,这将作为SSRS Tablix的数据集传递。
我正在尝试将查询的输出格式化为
DeviceId | Aisle | Level | Lift | MoveCount | FaultCount
D820 | Aisle8 | Level20 | Upper | 16 | 5
D818 | Aisle8 | Level18 | Upper | 36 | 31
D817 | Aisle8 | Level17 | Upper | 0 | 2
D811 | Aisle8 | Level11 | Upper | 10 | 0
以下查询适用于单个设备,但是如果WHERE子句更改为[走道]列表而不是单个特定设备,我不确定是否可以扩展它以及如何扩展它以显示计数。 [Aisle]和[Level]从DeviceId中的3位数字衍生而来,其中Dxyz => Aisle x,Level yz。
SELECT
dm.DeviceId
, 'Aisle'+RIGHT(LEFT(DeviceId,4),1) as [Aisle]
, 'Level'+RIGHT(DeviceId,2) as [Level]
, case when RIGHT(DeviceId,2) >= 11 then 'Upper' else 'Lower' end as [Lift]
, (SELECT COUNT(*) FROM DeviceMove WHERE DeviceId = 'D820' and TL_Event_Date BETWEEN '2020-01-10 09:15:38.980' and '2020-01-28 09:25:38.980') AS [MoveCount]
, (SELECT COUNT(*) FROM DeviceFaulted WHERE DeviceId = 'D820' and TL_Event_Date BETWEEN '2020-01-10 09:15:38.980' and '2020-01-28 09:25:38.980' ) AS [FaultCount]
FROM
DeviceMove dm
WHERE
dm.DeviceId = 'D820'
GROUP BY
dm.DeviceId
所以我想替换
WHERE
dm.DeviceId = 'D820'
具有如下所示(具体值将来自Report参数,而不是硬编码)
WHERE
'Aisle'+RIGHT(LEFT(DeviceId,4),1) in ('Aisle8', 'Aisle7', 'Aisle6')
我已经找到了使用common_table_expressions的解决方案-
;WITH cte1 AS(
SELECT
DeviceId
, COUNT(DeviceId) as [MoveCount]
FROM
DeviceMove
WHERE
DeviceId like 'OLS80[1-3]'
GROUP BY
DeviceId)
, cte2 AS(
SELECT
DeviceId
, COUNT(DeviceId) as [FaultCount]
FROM
DeviceFaulted
WHERE
DeviceId like 'OLS80[1-3]'
GROUP BY
DeviceId)
SELECT
moves.DeviceId
, 'Aisle'+RIGHT(LEFT(moves.DeviceId,4),1) as [Aisle]
, 'Level'+RIGHT(moves.DeviceId,2) as [Level]
, case when RIGHT(moves.DeviceId,2) >= 11 then 'Upper' else 'Lower' end as [Lift]
, moves.MoveCount
, faults.FaultCount
FROM
cte1 moves
FULL JOIN cte2 faults ON moves.DeviceId = faults.DeviceId
ORDER BY
[Aisle] desc, [Level] desc
哪个返回正确的值
DeviceId | Aisle | Level | Lift | MoveCount | FaultCount
----------+----------+-----------+---------+-------------+---------
D803 | Aisle8 | Level03 | Lower | 15515 | 708
D802 | Aisle8 | Level02 | Lower | 17039 | 384
D801 | Aisle8 | Level01 | Lower | 16306 | 399