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.