Я пишу SP в T-SQL, чтобы вернуть показатели «первого выхода» из тестовых данных, хранящихся в таблицах базы данных на SQL Server 2008 R2.У меня написано, что SP возвращает базовые данные для построения графиков в приложении, но я хотел бы добавить всплывающие подсказки, чтобы предоставить подробности за определенный период времени, когда пользователь наводит курсор на сегмент графика.
Примечание -Я не спрашиваю, как сделать часть интерфейса здесь, просто как получить данные.О пользовательском интерфейсе, о котором я расскажу позже ...
Вот упрощенная схема для хранения исходных данных:
CREATE TABLE [dbo].[TestRecords](
[TestRecordID] [int] NOT NULL,
[HostName] [varchar](25) NOT NULL,
[UnitSerial] [varchar](20) NOT NULL,
[PassFailStatus] [bit] NOT NULL,
[AssyLineID] [int] NOT NULL,
[TestDateTime] [datetime] NOT NULL)
Идея состоит в том, чтобы возвратить общее количество модулей, построенных правильно, за первоевремя, деленное на общее количество построенных блоков - это номер первого прохода.Мы хотим сделать это для любого количества сборочных линий (AssyLineID) за несколько произвольный период времени.
«Произвольный» в данном случае означает почасовой для данного дня или ежедневно в течение более длительного периода времени ...
Полученный набор данных представляет собой таблицу записей, подобную этой:
CREATE TABLE [dbo].[FpyValues](
[FpyValueID] [int] IDENTITY(1,1) NOT NULL,
[SessionID] [int] NOT NULL,
[DateTime] [datetime] NOT NULL,
[AssyLineID] [int] NOT NULL,
[Fpy] [float] NOT NULL,
[TotalUnits] [int] NOT NULL,
[FailedUnits] [int] NOT NULL)
Пока все хорошо, но возвращенное значение FPY не содержит много информации.Для интересных событий (относительно низкий или высокий FPY) команда по качеству хотела бы знать, какие типы единиц они строили и какие числа использовались для получения FPY - без ознакомления с еще одним отчетом.Я мог бы вернуться к базе данных, когда должна отображаться подсказка, но данные не будут такими же.Исходный набор данных учитывает единицу, которая потерпела неудачу в более ранний период времени, и не (ошибочно) считает ее хорошей единицей в текущий период времени.
Вот несколько упрощенная версия моего SP для полученияежечасный FPY для данного дня:
ALTER PROCEDURE [dbo].[GetHourlyFpy]
@ProdLineList VARCHAR(100),
@ReportDate DATETIME
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Fpy FLOAT, @Total FLOAT, @Failed FLOAT
DECLARE @SessionID INT;
DECLARE @TempList TABLE
(
LineID INT
);
DECLARE @LineID VARCHAR(10);
DECLARE @LineName VARCHAR(16);
DECLARE @FailedUnits TABLE
(
UnitSerial VARCHAR(12)
);
DECLARE @Start INT, @End INT, @Current INT;
DECLARE @StartTime DATETIME, @EndTime DATETIME;
-- unpack incoming comma-separated list of Production Line IDs into temp table
-- get session ID to identify results for this session
-- get the start and end hour values (@Start and @End)
-- Get the Date part of the incoming DATETIME value (time = 00:00:00.000)
-- loop through all production lines, creating result records as we go
WHILE EXISTS(SELECT * FROM @TempList)
BEGIN
SELECT TOP 1 @LineID = LineID FROM @TempList;
-- clear the failed units table
DELETE FROM @FailedUnits;
-- set the start time for reporting
SET @StartTime = (SELECT DATEADD(Hh, @Start, @ReportDate));
-- loop through all 1-hour periods for the day
SET @Current = @Start;
WHILE @Current < @End
BEGIN
SET @EndTime = (SELECT DATEADD(Hh, 1, @StartTime));
SET @Total = (SELECT COUNT(DISTINCT tr.UnitSerial)
FROM TestRecords
WHERE @StartTime <= tr.TestDateTime
AND tr.TestDateTime < @EndTime
AND tr.AssyLineID = @LineID
AND (NOT EXISTS
(SELECT UnitSerial FROM @FailedUnits f WHERE tr.UnitSerial = f.UnitSerial)));
SET @Failed = (SELECT COUNT(DISTINCT tr.UnitSerial)
FROM TestRecords tr
WHERE @StartTime <= tr.TestDateTime
AND tr.TestDateTime < @EndTime
AND tr.PassFailStatus = 0
AND tr.AssyLineID = @LineID
AND (NOT EXISTS
(SELECT UnitSerial FROM @FailedUnits f WHERE tr.UnitSerial = f.UnitSerial)));
-- populate the failed units list as needed
INSERT INTO @FailedUnits
SELECT DISTINCT tr.UnitSerial
FROM dbo.TestRecords tr
LEFT OUTER JOIN
@FailedUnits f ON tr.UnitSerial = f.UnitSerial
WHERE @StartTime <= tr.TestDateTime
AND tr.TestDateTime < @EndTime
AND tr.PassFailStatus = 0
AND tr.AssyLineID = @LineID
AND f.UnitSerial IS NULL;
IF (0 = @Total)
SET @Fpy = 0;
ELSE
SET @Fpy = (@Total - @Failed) / @Total;
INSERT INTO dbo.FpyValues (SessionID, [DateTime], ProductionLine, Fpy, TotalUnits, FailedUnits)
VALUES(@SessionID, @StartTime, @LineID, @Fpy, @Total, @Failed);
SET @StartTime = (SELECT DATEADD(Hh, 1, @StartTime));
SET @Current = @Current + 1;
END
-- we're done with this production line
DELETE FROM @TempList WHERE LineID = @LineID;
END
RETURN @SessionID;
END
Мне нужен способ заполнить таблицу с деталями для каждой сборочной линии для каждого периода времени следующим образом:
CREATE TABLE [dbo].[FpyUnits](
[FpyUnitID] [int] IDENTITY(1,1) NOT NULL,
[FpyValueID] [int] NOT NULL,
[DateTime] [datetime] NOT NULL,
[AssyLineID] [int] NOT NULL,
[UnitType] [varchar](25) NOT NULL,
[TotalUnits] [int] NOT NULL,
[FailedUnits] [int] NOT NULL)
Примечание Мне нужносоздайте и сохраните основную / родительскую запись на диск до сохранения подробных записей, поэтому у меня есть значение внешнего ключа (FpyValueID).
Один из способов, который я могу себе представить, - это изменить способ вычисления исходных данных и суммыданные из подробных записей для расчета общих значений FPY.Я также вижу, где мне может понадобиться использовать директиву GROUP BY, чтобы получить подробные значения.
У кого-нибудь есть предложения о том, как построить запросы SQL для извлечения этих данных без добавления дополнительных циклов?Это действительно долго, поэтому я уйду отсюда.Если вам нужна дополнительная информация, пожалуйста, спросите ...
Заранее спасибо за любые идеи / помощь, Дейв