SQL Join 2 Case из третьей таблицы - PullRequest
1 голос
/ 08 ноября 2019

Фон

У меня есть три таблицы:

  1. MetaMachine (MM)
  2. MetaShift (MS)
  3. MachineData (MD)

MM Содержит все относящиеся статические данные о конкретной машине, в том числе о том, какая рабочая смена ее эксплуатирует.

MS Содержит различные сдвиги, вспомогательные сдвиги, время начала (чч: мм) и продолжительность (ч) указанных сдвигов

MD Содержит датчикпоказания с машин, все с датой времени (DTS).

Проблема

Я хочу знать, что происходило в часы-призраки, т.е. когда машина работала без каких-либо операторов.

Логика, которую я хочу применить: (Обратите внимание, что это мой выдуманный SQL)

Select 
 MD.*
,MM.Shift 
    CASE
        WHEN Time(MD.[DTS]) > MS.[ShiftStartTime] & < (MS.[ShiftStartTime]+MS.[ShiftDuration]) THEN ‘In Shift’
        ELSE ‘Ghost’
    END AS IN_OUT_SHIFT
FROM MetaShift as MS, MachineData as MD
JOIN MetaMachine as MM on MD.MachineNR = MM.MachineNR

Идея состоит в том, что я могу объединить MD и MM, чтобы добавить сдвигимя в качестве столбца в MD, я знаю, нужно проверить в таблице MS, если записанная метка времени находится в какой-либо подмены в тот день.

Обратите внимание, что машина может иметь от 1 до 3 различных смен в зависимости от дня и типа смены.

Еще одна проблема, с которой я сталкиваюсь, это ночные смены, т.е. смены, которые начинаются примерно в 22:00 и заканчиваются в 06:00 на следующий день.

Таблицы примеров

MetaMachine    
|   MachineNr |       Shift      | Manufacturer |
--------------------------------------------------
|   1         |    2shift        |  Siemens     |
|   2         |    4shift        |  ABB         |
|   3         |    4shift        |  IKEA        |
|   4         |    TurkyShift    |  ABB         |


MachineData
|             Tstamp            |   MachineNr |   Sensor1 |   Sensor2 |
-----------------------------------------------------------------------
|    2019-05-11 01:00:00.000    |   1         |    10     |     -35   |
|    2019-05-11 01:30:00.000    |   2         |    10.1   |      19   |
|    2019-05-11 01:30:05.000    |   4         |    0.98   |     100   |
|    2019-05-12 01:00:00.000    |   1         |    3.7    |     58    |

MetaShift
|Shift  |Shift Name |WeekDay    |   ShiftStart  |Duration (h)   |Duration (s)   |
-----------------------------------------------------------------------------------------
|2shift |V1     |Monday     |05:54:00       |7,90       |28440  |
|2shift |V1     |Tuesday    |05:54:00       |7,90       |28440  |
|2shift |V1     |Wednesday  |05:54:00       |7,90       |28440  |
|2shift |V1     |Thursday   |05:54:00       |7,90       |28440  |
|2shift |V1     |Friday     |05:54:00       |7,90       |28440  |
|2shift |V1     |Saturday   |               |0      |   |
|2shift |V1     |Sunday     |               |0      |   |
|2shift |V2     |Monday     |14:00:00       |9,40       |33840  |
|2shift |V2     |Tuesday    |14:00:00       |9,40       |33840  |
|2shift |V2     |Wednesday  |14:00:00       |9,40       |33840  |
|2shift |V2     |Thursday   |14:00:00       |8,40       |30240  |
|2shift |V2     |Friday     |           |0      |   |
|2shift |V2     |Saturday   |           |0      |   |
|2shift |V2     |Sunday     |           |0      |   |
|4shift |V1     |Monday     |06:00:00       |8,00       |28800  |
|4shift |V1     |Tuesday    |06:00:00       |8,00       |28800  |
|4shift |V1     |Wednesday  |06:00:00       |8,00       |28800  |
|4shift |V1     |Thursday   |06:00:00       |8,00       |28800  |
|4shift |V1     |Friday     |06:00:00       |6,00       |21600  |
|4shift |V1     |Saturday   |06:00:00       |12,00      |43200  |
|4shift |V1     |Sunday     |06:00:00       |12,00      |43200  |
|4shift |V2     |Monday     |           |0      |   |

1 Ответ

0 голосов
/ 13 ноября 2019

Я решил это, но это, вероятно, не самый эффективный способ. :) Пожалуйста, если у вас есть какие-либо отзывы для повышения эффективности, я все уши.

select
    MD.Timestamp,
    case when ShiftString is null then 'Ghost' else Shift end GhostOrNoGhost 
    , *
from (
    SELECT 
        M.ShiftName
        ,(  
            select top 1 MS.ShiftName + ' ' + MS.ShiftSubName + ' ' + MS.ShiftDay + ' ' + convert(nvarchar(20),MS.ShiftStart) + case when Counts > 1 then ' xxx ' + convert(nvarchar(4), Counts) else '' end
            from (
                select MS.ShiftName, MS.ShiftSubName, MS.ShiftDay, MS.ShiftStart,
                    count(*) over () as Counts
                from MetaShift as MS
                where MS.ShiftName = MM.ShiftName
                and datename(dw,dateadd(second,-MS.ShiftDuration*3600,MD.Timestamp)) = MS.ShiftDay
                and convert(time, MD.Timestamp) >= MS.ShiftStart and MD.Timestamp < convert(datetime, convert(date,MD.Timestamp)) + dateadd(second,+MS.ShiftDuration*3600,convert(datetime,MS.ShiftStart)) 
            ) x
        ) ShiftString
        ,MD.*

    FROM [MachineData] as MD
    JOIN [MetaMachine] as MM on MM.MachineNr = MD.MachineNr
) x 
order by MD.Timestamp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...