【问题标题】:SQL Join 2 Case from a third table来自第三个表的 SQL Join 2 Case
【发布时间】:2019-11-13 20:51:21
【问题描述】:

背景

我有三张桌子:

  1. 元机器(MM)
  2. MetaShift (MS)
  3. 机器数据(MD)

MM 包含有关特定机器的所有相关静态数据,包括操作该机器的工人班次。

MS 包含所述班次的不同班次、子班次、StartTime(hh:mm) 和 Duration(h)

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      |   |

【问题讨论】:

  • 如果没有任何表结构,加上一些数据,然后是一些预期的结果,似乎有点难以理解。如果您可以制作一些简化的表格,可能只有足够的数据来得出一个示例结果。人们过去曾通过发布脚本来生成填充的表变量来提供此功能,例如
  • 虽然我知道您目前可能正在尝试设计表格
  • 我理解它很难理解,我将尝试找出一种以简单方式表示表格的方法。 :)
  • 如果可能的话,请与一些虚拟数据共享您的表结构
  • 我添加了一些结构相同的虚拟表,请注意每台机器每秒写入5行数据

标签: sql-server


【解决方案1】:

我解决了,但这可能不是最有效的方法。 :) 如果您对提高效率有任何反馈意见,我会全力以赴。

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

【讨论】:

    猜你喜欢
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 2015-02-14
    • 2014-01-13
    • 2014-03-11
    相关资源
    最近更新 更多