421 lines
21 KiB
Transact-SQL
421 lines
21 KiB
Transact-SQL
-- 产品会话管理相关表结构
|
||
-- 创建时间: 2026-04-01
|
||
-- 版本: 1.0
|
||
|
||
-- =============================================
|
||
-- 产品会话表
|
||
-- =============================================
|
||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session]') AND type in (N'U'))
|
||
BEGIN
|
||
CREATE TABLE [dbo].[mdl_production_session] (
|
||
[SessionId] UNIQUEIDENTIFIER NOT NULL CONSTRAINT [DF_mdl_production_session_SessionId] DEFAULT (NEWID()),
|
||
[ProductTypeCode] NVARCHAR(50) NOT NULL,
|
||
[ProductTypeName] NVARCHAR(200) NOT NULL,
|
||
[StationId] NVARCHAR(50) NOT NULL,
|
||
[StationName] NVARCHAR(200) NOT NULL,
|
||
[OperatorId] NVARCHAR(50) NOT NULL,
|
||
[OperatorName] NVARCHAR(100) NOT NULL,
|
||
[ShiftId] NVARCHAR(50) NOT NULL,
|
||
[ShiftName] NVARCHAR(100) NOT NULL,
|
||
[StartedAtUtc] DATETIME2(3) NOT NULL,
|
||
[EndedAtUtc] DATETIME2(3) NULL,
|
||
[Status] INT NOT NULL CONSTRAINT [DF_mdl_production_session_Status] DEFAULT (0), -- 0=InProgress, 1=CompletedOk, 2=CompletedNg, 3=Cancelled, 4=Paused
|
||
[Result] INT NOT NULL CONSTRAINT [DF_mdl_production_session_Result] DEFAULT (0), -- 0=Pending, 1=Ok, 2=Ng
|
||
[CurrentLayer] INT NOT NULL CONSTRAINT [DF_mdl_production_session_CurrentLayer] DEFAULT (0),
|
||
[TotalLayers] INT NOT NULL CONSTRAINT [DF_mdl_production_session_TotalLayers] DEFAULT (0),
|
||
[NgReason] NVARCHAR(500) NULL,
|
||
[Remark] NVARCHAR(1000) NULL,
|
||
[CreatedAtUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_CreatedAtUtc] DEFAULT (SYSUTCDATETIME()),
|
||
[UpdatedAtUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_UpdatedAtUtc] DEFAULT (SYSUTCDATETIME()),
|
||
[CreatedBy] NVARCHAR(100) NOT NULL CONSTRAINT [DF_mdl_production_session_CreatedBy] DEFAULT ('System'),
|
||
[UpdatedBy] NVARCHAR(100) NOT NULL CONSTRAINT [DF_mdl_production_session_UpdatedBy] DEFAULT ('System'),
|
||
CONSTRAINT [PK_mdl_production_session] PRIMARY KEY CLUSTERED ([SessionId] ASC)
|
||
);
|
||
|
||
-- 添加索引
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_StationId_Status] ON [dbo].[mdl_production_session] ([StationId], [Status]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_ProductTypeCode] ON [dbo].[mdl_production_session] ([ProductTypeCode]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_OperatorId] ON [dbo].[mdl_production_session] ([OperatorId]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_ShiftId] ON [dbo].[mdl_production_session] ([ShiftId]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_StartedAtUtc] ON [dbo].[mdl_production_session] ([StartedAtUtc]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_EndedAtUtc] ON [dbo].[mdl_production_session] ([EndedAtUtc]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_Status_Result] ON [dbo].[mdl_production_session] ([Status], [Result]);
|
||
|
||
PRINT '创建表 mdl_production_session 成功';
|
||
END
|
||
ELSE
|
||
BEGIN
|
||
PRINT '表 mdl_production_session 已存在,跳过创建';
|
||
END
|
||
|
||
-- =============================================
|
||
-- 产品会话事件表
|
||
-- =============================================
|
||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session_event]') AND type in (N'U'))
|
||
BEGIN
|
||
CREATE TABLE [dbo].[mdl_production_session_event] (
|
||
[EventId] UNIQUEIDENTIFIER NOT NULL CONSTRAINT [DF_mdl_production_session_event_EventId] DEFAULT (NEWID()),
|
||
[SessionId] UNIQUEIDENTIFIER NOT NULL,
|
||
[EventType] INT NOT NULL, -- 0=SessionCreated, 1=SessionArchived, 2=ProgressUpdated, 3=SessionPaused, 4=SessionResumed, 5=SessionCancelled, 6=LayerStarted, 7=LayerCompleted, 8=NgDetected, 9=ManualIntervention
|
||
[Description] NVARCHAR(500) NOT NULL,
|
||
[OperatorName] NVARCHAR(100) NOT NULL,
|
||
[EventTimeUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_event_EventTimeUtc] DEFAULT (SYSUTCDATETIME()),
|
||
[ExtendedProperties] NVARCHAR(MAX) NULL, -- JSON格式的扩展属性
|
||
[CreatedAtUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_event_CreatedAtUtc] DEFAULT (SYSUTCDATETIME()),
|
||
CONSTRAINT [PK_mdl_production_session_event] PRIMARY KEY CLUSTERED ([EventId] ASC)
|
||
);
|
||
|
||
-- 添加索引
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_event_SessionId] ON [dbo].[mdl_production_session_event] ([SessionId]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_event_EventType] ON [dbo].[mdl_production_session_event] ([EventType]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_event_EventTimeUtc] ON [dbo].[mdl_production_session_event] ([EventTimeUtc]);
|
||
|
||
-- 添加外键约束
|
||
ALTER TABLE [dbo].[mdl_production_session_event] WITH CHECK ADD CONSTRAINT [FK_mdl_production_session_event_mdl_production_session] FOREIGN KEY([SessionId])
|
||
REFERENCES [dbo].[mdl_production_session] ([SessionId])
|
||
ON DELETE CASCADE;
|
||
|
||
PRINT '创建表 mdl_production_session_event 成功';
|
||
END
|
||
ELSE
|
||
BEGIN
|
||
PRINT '表 mdl_production_session_event 已存在,跳过创建';
|
||
END
|
||
|
||
-- =============================================
|
||
-- 产品会话快照表(可选,用于保存会话的详细状态快照)
|
||
-- =============================================
|
||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session_snapshot]') AND type in (N'U'))
|
||
BEGIN
|
||
CREATE TABLE [dbo].[mdl_production_session_snapshot] (
|
||
[SnapshotId] UNIQUEIDENTIFIER NOT NULL CONSTRAINT [DF_mdl_production_session_snapshot_SnapshotId] DEFAULT (NEWID()),
|
||
[SessionId] UNIQUEIDENTIFIER NOT NULL,
|
||
[LayerNumber] INT NOT NULL,
|
||
[SnapshotType] INT NOT NULL, -- 0=LayerStart, 1=LayerEnd, 2=NgDetected, 3=ManualIntervention
|
||
[SnapshotData] NVARCHAR(MAX) NOT NULL, -- JSON格式的快照数据
|
||
[Images] NVARCHAR(MAX) NULL, -- JSON格式的图片路径列表
|
||
[InferenceResults] NVARCHAR(MAX) NULL, -- JSON格式的推理结果
|
||
[RuleResults] NVARCHAR(MAX) NULL, -- JSON格式的规则检查结果
|
||
[OperatorName] NVARCHAR(100) NULL,
|
||
[SnapshotTimeUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_snapshot_SnapshotTimeUtc] DEFAULT (SYSUTCDATETIME()),
|
||
[CreatedAtUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_snapshot_CreatedAtUtc] DEFAULT (SYSUTCDATETIME()),
|
||
CONSTRAINT [PK_mdl_production_session_snapshot] PRIMARY KEY CLUSTERED ([SnapshotId] ASC)
|
||
);
|
||
|
||
-- 添加索引
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_snapshot_SessionId] ON [dbo].[mdl_production_session_snapshot] ([SessionId]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_snapshot_LayerNumber] ON [dbo].[mdl_production_session_snapshot] ([LayerNumber]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_snapshot_SnapshotType] ON [dbo].[mdl_production_session_snapshot] ([SnapshotType]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_snapshot_SnapshotTimeUtc] ON [dbo].[mdl_production_session_snapshot] ([SnapshotTimeUtc]);
|
||
|
||
-- 添加外键约束
|
||
ALTER TABLE [dbo].[mdl_production_session_snapshot] WITH CHECK ADD CONSTRAINT [FK_mdl_production_session_snapshot_mdl_production_session] FOREIGN KEY([SessionId])
|
||
REFERENCES [dbo].[mdl_production_session] ([SessionId])
|
||
ON DELETE CASCADE;
|
||
|
||
PRINT '创建表 mdl_production_session_snapshot 成功';
|
||
END
|
||
ELSE
|
||
BEGIN
|
||
PRINT '表 mdl_production_session_snapshot 已存在,跳过创建';
|
||
END
|
||
|
||
-- =============================================
|
||
-- 产品会话配置表(可选,用于存储会话相关的配置信息)
|
||
-- =============================================
|
||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session_config]') AND type in (N'U'))
|
||
BEGIN
|
||
CREATE TABLE [dbo].[mdl_production_session_config] (
|
||
[ConfigId] UNIQUEIDENTIFIER NOT NULL CONSTRAINT [DF_mdl_production_session_config_ConfigId] DEFAULT (NEWID()),
|
||
[SessionId] UNIQUEIDENTIFIER NOT NULL,
|
||
[ConfigType] NVARCHAR(50) NOT NULL, -- 配置类型:Camera, Inference, Rules, etc.
|
||
[ConfigKey] NVARCHAR(100) NOT NULL,
|
||
[ConfigValue] NVARCHAR(MAX) NOT NULL,
|
||
[ConfigVersion] NVARCHAR(20) NULL,
|
||
[IsActive] BIT NOT NULL CONSTRAINT [DF_mdl_production_session_config_IsActive] DEFAULT (1),
|
||
[CreatedAtUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_config_CreatedAtUtc] DEFAULT (SYSUTCDATETIME()),
|
||
[UpdatedAtUtc] DATETIME2(3) NOT NULL CONSTRAINT [DF_mdl_production_session_config_UpdatedAtUtc] DEFAULT (SYSUTCDATETIME()),
|
||
CONSTRAINT [PK_mdl_production_session_config] PRIMARY KEY CLUSTERED ([ConfigId] ASC)
|
||
);
|
||
|
||
-- 添加索引
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_config_SessionId] ON [dbo].[mdl_production_session_config] ([SessionId]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_config_ConfigType] ON [dbo].[mdl_production_session_config] ([ConfigType]);
|
||
CREATE NONCLUSTERED INDEX [IX_mdl_production_session_config_ConfigKey] ON [dbo].[mdl_production_session_config] ([ConfigKey]);
|
||
|
||
-- 添加外键约束
|
||
ALTER TABLE [dbo].[mdl_production_session_config] WITH CHECK ADD CONSTRAINT [FK_mdl_production_session_config_mdl_production_session] FOREIGN KEY([SessionId])
|
||
REFERENCES [dbo].[mdl_production_session] ([SessionId])
|
||
ON DELETE CASCADE;
|
||
|
||
PRINT '创建表 mdl_production_session_config 成功';
|
||
END
|
||
ELSE
|
||
BEGIN
|
||
PRINT '表 mdl_production_session_config 已存在,跳过创建';
|
||
END
|
||
|
||
-- =============================================
|
||
-- 添加表注释
|
||
-- =============================================
|
||
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session]') AND type in (N'U'))
|
||
BEGIN
|
||
EXEC sp_addextendedproperty
|
||
@name = N'MS_Description',
|
||
@value = N'产品会话表,记录每个产品的装配过程信息',
|
||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||
@level1type = N'TABLE', @level1name = N'mdl_production_session';
|
||
END
|
||
|
||
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session_event]') AND type in (N'U'))
|
||
BEGIN
|
||
EXEC sp_addextendedproperty
|
||
@name = N'MS_Description',
|
||
@value = N'产品会话事件表,记录会话过程中的关键事件',
|
||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||
@level1type = N'TABLE', @level1name = N'mdl_production_session_event';
|
||
END
|
||
|
||
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session_snapshot]') AND type in (N'U'))
|
||
BEGIN
|
||
EXEC sp_addextendedproperty
|
||
@name = N'MS_Description',
|
||
@value = N'产品会话快照表,保存会话的详细状态快照数据',
|
||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||
@level1type = N'TABLE', @level1name = N'mdl_production_session_snapshot';
|
||
END
|
||
|
||
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mdl_production_session_config]') AND type in (N'U'))
|
||
BEGIN
|
||
EXEC sp_addextendedproperty
|
||
@name = N'MS_Description',
|
||
@value = N'产品会话配置表,存储会话相关的配置信息',
|
||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||
@level1type = N'TABLE', @level1name = N'mdl_production_session_config';
|
||
END
|
||
|
||
-- =============================================
|
||
-- 创建视图:会话统计视图
|
||
-- =============================================
|
||
IF NOT EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vw_production_session_statistics]'))
|
||
BEGIN
|
||
EXEC (N'
|
||
CREATE VIEW [dbo].[vw_production_session_statistics] AS
|
||
SELECT
|
||
s.ProductTypeCode,
|
||
s.ProductTypeName,
|
||
s.StationId,
|
||
s.StationName,
|
||
s.OperatorId,
|
||
s.OperatorName,
|
||
s.ShiftId,
|
||
s.ShiftName,
|
||
CAST(s.StartedAtUtc AS DATE) AS SessionDate,
|
||
COUNT(*) AS TotalSessions,
|
||
SUM(CASE WHEN s.Result = 1 THEN 1 ELSE 0 END) AS OkSessions,
|
||
SUM(CASE WHEN s.Result = 2 THEN 1 ELSE 0 END) AS NgSessions,
|
||
SUM(CASE WHEN s.Status = 0 THEN 1 ELSE 0 END) AS InProgressSessions,
|
||
SUM(CASE WHEN s.Status = 3 THEN 1 ELSE 0 END) AS CancelledSessions,
|
||
SUM(CASE WHEN s.Status = 4 THEN 1 ELSE 0 END) AS PausedSessions,
|
||
CAST(CASE WHEN COUNT(*) > 0 THEN SUM(CASE WHEN s.Result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) ELSE 0 END AS DECIMAL(5,2)) AS PassRate,
|
||
AVG(CASE WHEN s.EndedAtUtc IS NOT NULL THEN DATEDIFF(SECOND, s.StartedAtUtc, s.EndedAtUtc) END) AS AvgProcessingTimeSeconds
|
||
FROM [dbo].[mdl_production_session] s
|
||
GROUP BY
|
||
s.ProductTypeCode, s.ProductTypeName,
|
||
s.StationId, s.StationName,
|
||
s.OperatorId, s.OperatorName,
|
||
s.ShiftId, s.ShiftName,
|
||
CAST(s.StartedAtUtc AS DATE)
|
||
');
|
||
|
||
PRINT '创建视图 vw_production_session_statistics 成功';
|
||
END
|
||
ELSE
|
||
BEGIN
|
||
PRINT '视图 vw_production_session_statistics 已存在,跳过创建';
|
||
END
|
||
|
||
-- =============================================
|
||
-- 创建存储过程:清理过期会话
|
||
-- =============================================
|
||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[sp_cleanup_expired_sessions]') AND type in (N'P', N'PC'))
|
||
BEGIN
|
||
EXEC (N'
|
||
CREATE PROCEDURE [dbo].[sp_cleanup_expired_sessions]
|
||
@RetentionDays INT = 30,
|
||
@CleanedCount INT OUTPUT,
|
||
@FreedSpaceBytes BIGINT OUTPUT
|
||
AS
|
||
BEGIN
|
||
SET NOCOUNT ON;
|
||
|
||
DECLARE @CutoffDate DATETIME2 = DATEADD(DAY, -@RetentionDays, SYSUTCDATETIME());
|
||
DECLARE @DeletedCount INT = 0;
|
||
|
||
-- 计算要删除的会话数量
|
||
SELECT @DeletedCount = COUNT(*)
|
||
FROM [dbo].[mdl_production_session]
|
||
WHERE EndedAtUtc < @CutoffDate;
|
||
|
||
-- 删除过期会话(级联删除相关事件和快照)
|
||
DELETE FROM [dbo].[mdl_production_session]
|
||
WHERE EndedAtUtc < @CutoffDate;
|
||
|
||
-- 返回结果
|
||
SET @CleanedCount = @DeletedCount;
|
||
SET @FreedSpaceBytes = @DeletedCount * 1024; -- 假设每个会话占用1KB
|
||
|
||
RETURN 0;
|
||
END
|
||
');
|
||
|
||
PRINT '创建存储过程 sp_cleanup_expired_sessions 成功';
|
||
END
|
||
ELSE
|
||
BEGIN
|
||
PRINT '存储过程 sp_cleanup_expired_sessions 已存在,跳过创建';
|
||
END
|
||
|
||
-- =============================================
|
||
-- 创建存储过程:获取会话统计信息
|
||
-- =============================================
|
||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[sp_get_session_statistics]') AND type in (N'P', N'PC'))
|
||
BEGIN
|
||
EXEC (N'
|
||
CREATE PROCEDURE [dbo].[sp_get_session_statistics]
|
||
@StartTime DATETIME2,
|
||
@EndTime DATETIME2,
|
||
@ProductTypeCode NVARCHAR(50) = NULL,
|
||
@StationId NVARCHAR(50) = NULL,
|
||
@OperatorId NVARCHAR(50) = NULL,
|
||
@ShiftId NVARCHAR(50) = NULL
|
||
AS
|
||
BEGIN
|
||
SET NOCOUNT ON;
|
||
|
||
SELECT
|
||
COUNT(*) AS TotalSessions,
|
||
SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) AS OkSessions,
|
||
SUM(CASE WHEN Result = 2 THEN 1 ELSE 0 END) AS NgSessions,
|
||
SUM(CASE WHEN Status = 0 THEN 1 ELSE 0 END) AS InProgressSessions,
|
||
SUM(CASE WHEN Status = 3 THEN 1 ELSE 0 END) AS CancelledSessions,
|
||
SUM(CASE WHEN Status = 4 THEN 1 ELSE 0 END) AS PausedSessions,
|
||
CAST(CASE WHEN COUNT(*) > 0 THEN SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) ELSE 0 END AS DECIMAL(5,2)) AS PassRate,
|
||
AVG(CASE WHEN EndedAtUtc IS NOT NULL THEN DATEDIFF(SECOND, StartedAtUtc, EndedAtUtc) END) AS AvgProcessingTimeSeconds,
|
||
COUNT(*) / NULLIF(SUM(DATEDIFF(HOUR, StartedAtUtc, EndedAtUtc)), 0) AS ThroughputPerHour
|
||
FROM [dbo].[mdl_production_session]
|
||
WHERE StartedAtUtc >= @StartTime
|
||
AND StartedAtUtc <= @EndTime
|
||
AND (@ProductTypeCode IS NULL OR ProductTypeCode = @ProductTypeCode)
|
||
AND (@StationId IS NULL OR StationId = @StationId)
|
||
AND (@OperatorId IS NULL OR OperatorId = @OperatorId)
|
||
AND (@ShiftId IS NULL OR ShiftId = @ShiftId);
|
||
|
||
-- 按产品类型分组统计
|
||
SELECT
|
||
ProductTypeCode,
|
||
ProductTypeName,
|
||
COUNT(*) AS TotalSessions,
|
||
SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) AS OkSessions,
|
||
SUM(CASE WHEN Result = 2 THEN 1 ELSE 0 END) AS NgSessions,
|
||
CAST(CASE WHEN COUNT(*) > 0 THEN SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) ELSE 0 END AS DECIMAL(5,2)) AS PassRate
|
||
FROM [dbo].[mdl_production_session]
|
||
WHERE StartedAtUtc >= @StartTime
|
||
AND StartedAtUtc <= @EndTime
|
||
AND (@ProductTypeCode IS NULL OR ProductTypeCode = @ProductTypeCode)
|
||
AND (@StationId IS NULL OR StationId = @StationId)
|
||
AND (@OperatorId IS NULL OR OperatorId = @OperatorId)
|
||
AND (@ShiftId IS NULL OR ShiftId = @ShiftId)
|
||
GROUP BY ProductTypeCode, ProductTypeName
|
||
ORDER BY TotalSessions DESC;
|
||
|
||
-- 按工位分组统计
|
||
SELECT
|
||
StationId,
|
||
StationName,
|
||
COUNT(*) AS TotalSessions,
|
||
SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) AS OkSessions,
|
||
SUM(CASE WHEN Result = 2 THEN 1 ELSE 0 END) AS NgSessions,
|
||
CAST(CASE WHEN COUNT(*) > 0 THEN SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) ELSE 0 END AS DECIMAL(5,2)) AS PassRate,
|
||
COUNT(*) / NULLIF(AVG(DATEDIFF(HOUR, StartedAtUtc, EndedAtUtc)), 0) AS ThroughputPerHour
|
||
FROM [dbo].[mdl_production_session]
|
||
WHERE StartedAtUtc >= @StartTime
|
||
AND StartedAtUtc <= @EndTime
|
||
AND (@ProductTypeCode IS NULL OR ProductTypeCode = @ProductTypeCode)
|
||
AND (@StationId IS NULL OR StationId = @StationId)
|
||
AND (@OperatorId IS NULL OR OperatorId = @OperatorId)
|
||
AND (@ShiftId IS NULL OR ShiftId = @ShiftId)
|
||
AND EndedAtUtc IS NOT NULL
|
||
GROUP BY StationId, StationName
|
||
ORDER BY TotalSessions DESC;
|
||
|
||
-- 按操作员分组统计
|
||
SELECT
|
||
OperatorId,
|
||
OperatorName,
|
||
COUNT(*) AS TotalSessions,
|
||
SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) AS OkSessions,
|
||
SUM(CASE WHEN Result = 2 THEN 1 ELSE 0 END) AS NgSessions,
|
||
CAST(CASE WHEN COUNT(*) > 0 THEN SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) ELSE 0 END AS DECIMAL(5,2)) AS PassRate,
|
||
AVG(DATEDIFF(SECOND, StartedAtUtc, EndedAtUtc)) AS AvgProcessingTimeSeconds
|
||
FROM [dbo].[mdl_production_session]
|
||
WHERE StartedAtUtc >= @StartTime
|
||
AND StartedAtUtc <= @EndTime
|
||
AND (@ProductTypeCode IS NULL OR ProductTypeCode = @ProductTypeCode)
|
||
AND (@StationId IS NULL OR StationId = @StationId)
|
||
AND (@OperatorId IS NULL OR OperatorId = @OperatorId)
|
||
AND (@ShiftId IS NULL OR ShiftId = @ShiftId)
|
||
AND EndedAtUtc IS NOT NULL
|
||
GROUP BY OperatorId, OperatorName
|
||
ORDER BY TotalSessions DESC;
|
||
|
||
-- 按日期分组统计
|
||
SELECT
|
||
CAST(StartedAtUtc AS DATE) AS SessionDate,
|
||
COUNT(*) AS TotalSessions,
|
||
SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) AS OkSessions,
|
||
SUM(CASE WHEN Result = 2 THEN 1 ELSE 0 END) AS NgSessions,
|
||
CAST(CASE WHEN COUNT(*) > 0 THEN SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) ELSE 0 END AS DECIMAL(5,2)) AS PassRate,
|
||
COUNT(*) / NULLIF(AVG(DATEDIFF(HOUR, StartedAtUtc, EndedAtUtc)), 0) AS ThroughputPerHour
|
||
FROM [dbo].[mdl_production_session]
|
||
WHERE StartedAtUtc >= @StartTime
|
||
AND StartedAtUtc <= @EndTime
|
||
AND (@ProductTypeCode IS NULL OR ProductTypeCode = @ProductTypeCode)
|
||
AND (@StationId IS NULL OR StationId = @StationId)
|
||
AND (@OperatorId IS NULL OR OperatorId = @OperatorId)
|
||
AND (@ShiftId IS NULL OR ShiftId = @ShiftId)
|
||
AND EndedAtUtc IS NOT NULL
|
||
GROUP BY CAST(StartedAtUtc AS DATE)
|
||
ORDER BY SessionDate;
|
||
|
||
-- 按班次分组统计
|
||
SELECT
|
||
ShiftId,
|
||
ShiftName,
|
||
COUNT(*) AS TotalSessions,
|
||
SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) AS OkSessions,
|
||
SUM(CASE WHEN Result = 2 THEN 1 ELSE 0 END) AS NgSessions,
|
||
CAST(CASE WHEN COUNT(*) > 0 THEN SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) ELSE 0 END AS DECIMAL(5,2)) AS PassRate,
|
||
COUNT(*) / NULLIF(AVG(DATEDIFF(HOUR, StartedAtUtc, EndedAtUtc)), 0) AS ThroughputPerHour
|
||
FROM [dbo].[mdl_production_session]
|
||
WHERE StartedAtUtc >= @StartTime
|
||
AND StartedAtUtc <= @EndTime
|
||
AND (@ProductTypeCode IS NULL OR ProductTypeCode = @ProductTypeCode)
|
||
AND (@StationId IS NULL OR StationId = @StationId)
|
||
AND (@OperatorId IS NULL OR OperatorId = @OperatorId)
|
||
AND (@ShiftId IS NULL OR ShiftId = @ShiftId)
|
||
AND EndedAtUtc IS NOT NULL
|
||
GROUP BY ShiftId, ShiftName
|
||
ORDER BY TotalSessions DESC;
|
||
END
|
||
');
|
||
|
||
PRINT '创建存储过程 sp_get_session_statistics 成功';
|
||
END
|
||
ELSE
|
||
BEGIN
|
||
PRINT '存储过程 sp_get_session_statistics 已存在,跳过创建';
|
||
END
|
||
|
||
PRINT '产品会话管理相关表结构创建完成';
|