从两个表中选择计数,并以指定的格式输出结果

问题描述 投票:0回答:1

我有两个具有不同整体结构的表,但是它们共享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')
sql-server ssrs-2016
1个回答
0
投票

我已经找到了使用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
© www.soinside.com 2019 - 2024. All rights reserved.