Выберите счетчики из двух таблиц и выведите результаты в указанном формате - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть две таблицы с разными общими структурами, но они имеют 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         |  ...
...

В обеих таблицах больше столбцов, но для заполнения WHERE необходимы только DeviceId и TL_Event_Date пункт запроса.

Я хотел бы получить счетчик количества ходов и сбоев для указанного c идентификатора устройства в заданном временном диапазоне, который будет передан в качестве набора данных для таблицы SSRS.

Я пытаюсь отформатировать вывод запроса как

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 изменено, чтобы быть списком [Проходов], а не отдельным указанным c устройством. [Проход] и [Уровень] являются производными от 3 цифр в DeviceId, где Dxyz => Проход x, Уровень 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'

С чем-то вроде следующего (хотя указанные c значения будут исходить из параметров отчета, а не будут жестко закодированы)

WHERE
    'Aisle'+RIGHT(LEFT(DeviceId,4),1) in ('Aisle8', 'Aisle7', 'Aisle6')

1 Ответ

0 голосов
/ 06 апреля 2020

Я нашел решение с использованием 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
...