SQL percent completion query without cross-product duplication

48 views Asked by At

Edit: The DBMS being used is Microsoft SQL Server 2016 (13.0.5888.11)

I am starting to learn SQL through my job at a manufacturing facility where we are attempting to track product flow and delivery. Unfortunately, the software we are using to do this does not have their database documented whatsoever, so I have been trying to make sense of things as I go along. Forgive me if the formatting of this question is ugly, it will be my first question ever posted on here.

I want to create a SQL script that will track our % completion using the following calculation:

(Maximum operation completed / total operations in the process) x 100

Essentially what I'm trying to accomplish is to take the following two tables:

Product Transactions Table - Maximum Operation Completed per Serial

Serial Number Batch Name Process Description Operation Name Operation Sequence Max Operation Rank
001 Batch1 Process1 Operation1 1.0 1
002 Batch1 Process1 Operation3 3.0 1
001 Batch2 Process2 Operation1 1.0 1
001 Batch3 Process3 Operation2 2.0 1

Processes & Operations Table - Total Operations per Process

Process Name Operation Name Operation Sequence Process Flow Operation Count
Process1 Operation1 0 4
Process1 Operation2 1 4
Process1 Operation3 2 4
Process1 Operation4 3 4
Process2 Operation1 0 2
Process2 Operation2 1 2
Process3 Operation1 0 2
Process3 Operation2 1 2

and turn it into the following table:

Transactions Percent Completion Table

Serial Number Batch Name Process Description Operation Name Operation Sequence Process Flow Operation Count Percent Completion
001 Batch1 Process1 Operation1 1.0 4.0 25%
002 Batch1 Process1 Operation3 3.0 4.0 75%
001 Batch2 Process2 Operation1 1.0 2.0 50%
001 Batch3 Process3 Operation2 2.0 2.0 100%

I have the following script that gets the maximum operation completed per serial number (which is what I want):

SELECT *
FROM
(
SELECT SerialNumbers.Identifier, Batches.Name AS BatchName, Processes.Description AS ProcessDescription, 
Processes.Revision AS ProcessRevision, OperationBases.Sequence + 1.0 AS OperationSequence, 
OperationDefinitions.Name AS OperationName,  ProductTransactions.CycleTime* 60.0 AS CycleTime, 
ROW_NUMBER() OVER (PARTITION BY ItemInventories.Identifier ORDER BY OperationBases.Sequence DESC, ProductTransactions.CycleTime DESC) as MaxOperationRank

FROM ProductTransactions
LEFT JOIN SerialNumbers
    ON SerialNumbers.ID = ProductTransactions.SerialNumberID
LEFT JOIN BatchRoutes
    ON BatchRoutes.ID = ProductTransactions.BatchRouteID
LEFT JOIN Batches
    ON Batches.ID = BatchRoutes.BatchID
LEFT JOIN Processes
    ON Processes.ID = Batches.ProcessID
LEFT JOIN OperationBases
   ON OperationBases.ID = BatchRoutes.OperationID
LEFT JOIN OperationBases_Operation
   ON OperationBases.ID = OperationBases_Operation.ID
LEFT JOIN OperationDefinitions
   ON OperationBases_Operation.ID = OperationDefinitions.Operation_ID

) AS subQuery
WHERE MaxOperationRank = 1
  • ProductTransactions is where every transaction done on a product is stored (such as screwing parts together, cutting a part, etc.),
  • BatchRoutes is the bridge between ProductTransactions and Batches (Stores whether some quantity of a batch failed transactions, which operation they failed/passed at, etc.)
  • Batches is where basic batch data is stored (batch name, quantity of parts in a batch, etc.)
  • Processes refer to what overall process the product goes through (Inspection, Part Prep, Finish to Drawing Dimensions, etc.)
  • OperationBases, OperationBases_Operation, and OperationDefinitions refer to all the individual Operations (or steps) within a Process and all data associated with it. This stores the sequence number, which tells you which operation you are on (it is base 0 so I add 1 to it).

I also have the following script that goes through the Processes data table independent of any transactions so that the operations per process can be counted:

SELECT Processes.Name AS ProcessName, Processes.Description, Processes.Revision, Processes.LatestVersion, 
Processes.CurrentVersion, OperationDefinitions.Name AS OperationName, OperationBases.Sequence AS OperationSequence, 
OperationBases_Operation.IsOutOfRoute AS OutOfRouteOperation, Processes.TemplateID AS ProcTemplate, 
ProcessFlows.TemplateID AS ProcFlowTemplate, Processes.Deleted, Processes.ID AS ProcessID, OperationBases.ID AS OperationID, 
COUNT(OperationBases.Sequence) OVER (PARTITION BY Processes.ID ORDER BY Processes.Revision DESC, OperationBases_Operation.IsOutOfRoute ASC) AS ProcessFlowOperationCount
FROM Processes
LEFT JOIN ProcessFlows
    ON Processes.ID  = ProcessFlows.ProcessID
LEFT JOIN OperationBases
   ON ProcessFlows.ID = OperationBases.ProcessFlowID
LEFT JOIN OperationBases_Operation
   ON OperationBases.ID = OperationBases_Operation.ID
LEFT JOIN OperationDefinitions
   ON OperationBases_Operation.ID = OperationDefinitions.Operation_ID

I would like to combine these two queries together without them interacting too much with each other but still being associated. I have tried making either a subquery within the other but because there are multiple operations linked to each process I end up getting a cross product. I have a feeling it may be a JOIN issue where I'm not being restrictive enough, but I'm not too sure. Is there a way to keep these queries apart but still be linked in some way?

Thanks so much for your help in advance! I look forward to learning more.

0

There are 0 answers