Sometimes requirements make things...difficult and therefore interesting.
So an integration customer wanted a daily transaction report formatted in a certain way to allow their ERP system to ingest the data in order to update their inventory numbers.
This would usually be a straightforward transaction dump, formatted to whatever format their system required. However, in the event that a transaction was updated after the fact, the customer did not want to see the new value for the transaction...they wanted the difference between the original transaction and the updated transaction. Simple enough, yeah?
Not really, because of the way our system handled transaction updates. When an update occurred, the quantity value of the original transaction was shifted to a separate XTRAN transaction and replaced with the new quantity value.
So in order to accomplish their desired output, I had to get a little crazy with WHILE loops and temp tables in order to shift values back to their original positions to then be able to calculate the difference. Things got even crazier when you considered the possibility of multiple updates on the same original transaction.
Excited for the challenge, I set about writing the solution...while working from 'home' over a few nice sunny days on 'vacation' at Lakeside.
BEGIN
SET NOCOUNT ON;
--*******************************************
-- TELERIK NOT SHOWING DATA SOURCE FIELDS IF STORED PROCEDURE USES TEMP TABLES FIX
-- source of solution: https://www.telerik.com/forums/temporary-table-in-stored-proc
IF 1=0
BEGIN
SET FMTONLY OFF
END
--*******************************************
DECLARE
@counter INT = 1
,@loopCounter INT = 0
,@rowCount INT = 0
,@loopRowCount INT = 0
,@currentTransNo NVARCHAR(35) = ''
--=========================================================
-- first get yesterday's transactions
SELECT *
INTO #YESTERDAY
FROM
(
SELECT
TRANS.transnumber
,TRANS.station
,TRANS.bin
,TRANS.Item
,TRANS.OldItem
,TRANS.employee
,TRANS.User1
,TRANS.User3
,TRANS.User2
,TRANS.User4
,TRANS.cost
,TRANS.quantity
,TRANS.Transdate
,TRANS.Transtime
,TRANS.[type]
,TRANS.TypeDescription
,TRANS.binqty
,TRANS.User5
,TRANS.SerialID
,TRANS.User6
,TRANS.RelatedKey
,TRANS.[Status]
,TRANS.CribBin
,TRANS.BatchId
,TRANS.IssuedTo
,TRANS.Consignment
,TRANS.OtherCribBin
,TRANS.WONo
,TRANS.TransUsage
,TRANS.RepairCalCycle
,TRANS.Crib
,TRANS.LotNo
,TRANS.UsageType
,TRANS.UsageCribBin
,TRANS.UsageItemNumber
,TRANS.ReservationNo
,TRANS.SubType
,TRANS.OtherSiteNo
,TRANS.CycleCountClassNo
,TRANS.ExpectedAccuracy
,TRANS.TransRFIDNo
,TRANS.LocalTransDate
,TRANSDETAIL.TransReasonCode
FROM
REDACTED_CLOUD_01.CM01.dbo.TRANS AS TRANS LEFT OUTER JOIN
REDACTED_CLOUD_01.CM01.dbo.Crib AS CRIB ON TRANS.Crib = CRIB.Crib LEFT OUTER JOIN
REDACTED_CLOUD_01.CM01.dbo.TRANSDETAIL AS TRANSDETAIL ON TRANS.transnumber = TRANSDETAIL.TransNo
WHERE
CAST(Transdate AS DATE) = CAST(DATEADD(day,-1,GETDATE()) AS DATE)
AND Crib.SiteID = 'REDACTED'
AND (
(
TRANSDETAIL.TransReasonCode <> 'NB'
AND TRANSDETAIL.TransReasonCode IS NOT NULL
)
OR (TRANSDETAIL.TransReasonCode IS NULL)
)
AND (
TRANS.bin <> 'CANDYBIN'
OR TRANS.Item <> 'REDACTEDCANDY'
)
) AS yesterday
--==========================================================================
-- Ok, first chunk of logic to "show the difference in values"
-- for the UPDATE/XTRAN tansactions
-- We'll do the one where the UPDATE takes place on a different day
--==========================================================================
-- get two whole months of transactions so that we definitely capture the
-- past month/30 days...many fields in case we need them.
SELECT *
INTO #WHOLEMONTH
FROM
(
SELECT
TRANS.transnumber
,TRANS.station
,TRANS.bin
,TRANS.Item
,TRANS.OldItem
,TRANS.employee
,TRANS.User1
,TRANS.User3
,TRANS.User2
,TRANS.User4
,TRANS.cost
,TRANS.quantity
,TRANS.Transdate
,TRANS.Transtime
,TRANS.type
,TRANS.TypeDescription
,TRANS.binqty
,TRANS.User5
,TRANS.SerialID
,TRANS.User6
,TRANS.RelatedKey
,TRANS.Status
,TRANS.CribBin
,TRANS.BatchId
,TRANS.IssuedTo
,TRANS.Consignment
,TRANS.OtherCribBin
,TRANS.WONo
,TRANS.TransUsage
,TRANS.RepairCalCycle
,TRANS.Crib
,TRANS.LotNo
,TRANS.UsageType
,TRANS.UsageCribBin
,TRANS.UsageItemNumber
,TRANS.ReservationNo
,TRANS.SubType
,TRANS.OtherSiteNo
,TRANS.CycleCountClassNo
,TRANS.ExpectedAccuracy
,TRANS.TransRFIDNo
,TRANS.LocalTransDate
FROM
REDACTED_CLOUD_01.CM01.dbo.TRANS AS TRANS LEFT OUTER JOIN
REDACTED_CLOUD_01.CM01.dbo.Crib AS CRIB ON TRANS.Crib = CRIB.Crib
WHERE
CAST(Transdate AS DATE) >= CAST(DATEADD(month,-2,GETDATE()) AS DATE)
AND Crib.SiteID = 'REDACTED'
AND (
TRANS.bin <> 'CANDYBIN'
OR TRANS.Item <> 'REDACTEDCANDY'
)
) AS wholemonth
-- ok, now get just the XTRANS
SELECT *
INTO #WHOLEMONTH_XTRAN_TRANSNO
FROM
(
SELECT DISTINCT BatchId
FROM #WHOLEMONTH AS blah
WHERE TypeDescription = 'XTRAN'
) AS wholemonth_xtran_transno
-- now get a list of the original transactions for XTRANS
SELECT *
INTO #WHOLEMONTH_XTRAN_OGTRANS
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY transnumber) AS theRow
,transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,'OG' AS [Sequence]
FROM #WHOLEMONTH AS blah
WHERE transnumber IN (SELECT BatchId FROM #WHOLEMONTH_XTRAN_TRANSNO)
) AS wholemonth_xtran_ogtrans
-- now just the XTRANS where the items match (because the XTRAN BatchId
- can still be the same for ISSUES that are not the same item
SELECT *
INTO #WHOLEMONTH_XTRAN_JUSTRELEVANTXTRAN
FROM
(
SELECT
b.transnumber
,b.Item
,b.quantity
,b.Transdate
,b.Transtime
,b.BatchId
,b.TypeDescription
,ROW_NUMBER() OVER (PARTITION BY b.BatchId ORDER BY b.Transdate,b.Transtime) AS [Sequence]
FROM
#WHOLEMONTH_XTRAN_OGTRANS AS a INNER JOIN
#WHOLEMONTH AS b ON a.Item = b.Item AND a.transnumber = b.BatchId
WHERE b.TypeDescription = 'XTRAN'
) AS wholemonth_xtran_justrelevantxtran
-- ok, now a while loop to itterate through the OG trans rows, do some
-- stuff, and then dump that stuff into a temp table to use later.
SELECT @rowCount = COUNT(theRow) FROM #WHOLEMONTH_XTRAN_OGTRANS
DROP TABLE IF EXISTS #INSIDELOOP
CREATE TABLE #INSIDELOOP
(
transnumber NVARCHAR(30) NOT NULL
,Item NVARCHAR(30) NOT NULL
,ParentTransQty INT NULL
,OGTransQty INT NULL
,ShiftedTransQty INT NULL
,DifferenceQty INT NULL
,Transdate DATETIME NULL
,Transtime TIME NULL
,TypeDescription NVARCHAR(30) NULL
,OGTrans NVARCHAR(30) NULL
,[Sequence] NVARCHAR(10) NULL
)
WHILE @counter <= @rowCount
BEGIN
-- We need to get the max theRow number where the XTRAN batch id =
-- the OG transnumber and set a variable to that theRow number.
-- Then use that variable to WHILE through stuff and shuffle values
-- for the transactions.
SELECT @loopRowCount =
COUNT([Sequence])
FROM #WHOLEMONTH_XTRAN_JUSTRELEVANTXTRAN
WHERE BatchId IN (SELECT transnumber FROM #WHOLEMONTH_XTRAN_OGTRANS WHERE theRow = @counter)
SET @loopRowCount += 1 -- add 1 to account for the OG parent transaction
-- now the next while loop to do some stuff I don't know what yet
SET @loopCounter = 1
WHILE @loopCounter <= @loopRowCount
BEGIN
-- get the first row and 'correct' its value....
-- the 'original' value of the transaction will be
-- the first XTRAN(if multiple)
IF @loopCounter = 1 -- first run of next inside loop
BEGIN
INSERT INTO #INSIDELOOP (transnumber,Item,ParentTransQty,OGTransQty,ShiftedTransQty,DifferenceQty,Transdate,Transtime,TypeDescription,OGTrans,[Sequence])
SELECT
OG.transnumber
,OG.Item
,OG.quantity AS ParentTransQty
,OG.quantity AS OGTransQty
,XTRAN.quantity AS ShiftedTransQty
,0 AS DifferenceQty
,OG.Transdate
,OG.Transtime
,OG.TypeDescription
,OG.transnumber AS OGTrans
,OG.[Sequence]
FROM
(
SELECT
transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,[Sequence]
FROM #WHOLEMONTH_XTRAN_OGTRANS
WHERE theRow = @counter
) AS OG LEFT OUTER JOIN
(
SELECT
transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,[Sequence]
FROM #WHOLEMONTH_XTRAN_JUSTRELEVANTXTRAN
) AS XTRAN ON OG.transnumber = XTRAN.BatchId AND OG.Item = XTRAN.Item AND XTRAN.[Sequence] = @loopCounter -- 1
SELECT @currentTransNo = transnumber FROM #WHOLEMONTH_XTRAN_OGTRANS WHERE theRow = @counter
END
ELSE IF @loopCounter = @loopRowCount AND @loopCounter > 1 -- ELSE IF to handle the last run so we can compare last XTRAN to OG trans again
BEGIN
INSERT INTO #INSIDELOOP (transnumber,Item,ParentTransQty,OGTransQty,ShiftedTransQty,DifferenceQty,Transdate,Transtime,TypeDescription,OGTrans,[Sequence])
SELECT
XTRAN.transnumber
,XTRAN.Item
,OG.quantity AS ParentTransQty
,XTRAN.quantity AS OGTransQty
,OG.quantity AS ShiftedTransQty
,OG.quantity - XTRAN.quantity AS DifferenceQty
,XTRAN.Transdate
,XTRAN.Transtime
,XTRAN.TypeDescription
,XTRAN.BatchId AS OGTrans
,XTRAN.[Sequence]
FROM
(
SELECT
transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,[Sequence]
FROM #WHOLEMONTH_XTRAN_OGTRANS
WHERE theRow = @counter
) AS OG LEFT OUTER JOIN
(
SELECT
transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,[Sequence]
FROM #WHOLEMONTH_XTRAN_JUSTRELEVANTXTRAN
) AS XTRAN ON OG.transnumber = XTRAN.BatchId AND OG.Item = XTRAN.Item AND XTRAN.[Sequence] = @loopRowCount - 1 -- final XTRAN
END
ELSE IF @loopCounter < @loopRowCount AND @loopCounter > 1
BEGIN
-- ELSE sql statements here to handle any non-first,
-- non-last XTRANS, comparing XTRAN to XTRAN
INSERT INTO #INSIDELOOP (transnumber,Item,ParentTransQty,OGTransQty,ShiftedTransQty,DifferenceQty,Transdate,Transtime,TypeDescription,OGTrans,[Sequence])
SELECT
XTRAN.transnumber
,XTRAN.Item
,OG.quantity AS ParentTransQty
,XTRAN.quantity AS OGTransQty
,XTRAN2.quantity AS ShiftedTransQty
,XTRAN2.quantity - XTRAN.quantity AS DifferenceQty
,XTRAN.Transdate
,XTRAN.Transtime
,XTRAN.TypeDescription
,XTRAN.BatchId AS OGTrans
,XTRAN.[Sequence]
FROM
(
SELECT
transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,[Sequence]
FROM #WHOLEMONTH_XTRAN_JUSTRELEVANTXTRAN
WHERE BatchId = @currentTransNo AND [Sequence] = @loopCounter - 1
) AS XTRAN LEFT OUTER JOIN
(
SELECT
transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,[Sequence]
FROM #WHOLEMONTH_XTRAN_JUSTRELEVANTXTRAN
) AS XTRAN2 ON XTRAN.BatchId = XTRAN2.BatchId AND XTRAN.Item = XTRAN2.Item AND XTRAN2.[Sequence] = @loopCounter LEFT OUTER JOIN
(
SELECT
transnumber
,Item
,quantity
,Transdate
,Transtime
,BatchId
,TypeDescription
,[Sequence]
FROM #WHOLEMONTH_XTRAN_OGTRANS
WHERE Transnumber = @currentTransNo
) AS OG ON XTRAN.BatchId = OG.Transnumber AND XTRAN.Item = OG.Item
END
SET @loopCounter += 1
END
SET @counter += 1
END
-- now get just the OG row from the #INSIDELOOP dataset and add row numbers.
SELECT *
INTO #INSIDELOOP_OGROWS
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY transnumber) AS theRow
,transnumber
,Item
,ParentTransQty
,OGTransQty
,ShiftedTransQty
,DifferenceQty
,Transdate
,Transtime
,TypeDescription
,OGTrans
,[Sequence]
FROM #INSIDELOOP AS blah
WHERE [Sequence] = 'OG'
) AS insidelooprows
-- ok, I think we're going to have to loop again to better determine which
-- of the scenarios these transaction updates might be:
-- 1. Same day
-- 2. Different Day
-- reset the rowCount and counter variable
SELECT @rowCount = COUNT(theRow) FROM #INSIDELOOP_OGROWS
SELECT @counter = 1
-- create another temp table to dump the results of the looping into
DROP TABLE IF EXISTS #SECONDINSIDELOOP
CREATE TABLE #SECONDINSIDELOOP
(
transnumber NVARCHAR(30) NULL
,Item NVARCHAR(30) NULL
,ParentTransQty INT NULL
,OGTransQty INT NULL
,ShiftedTransQty INT NULL
,DifferenceQty INT NULL
,Transdate DATETIME NULL
,Transtime TIME NULL
,TypeDescription NVARCHAR(30) NULL
,OGTrans NVARCHAR(30) NULL
,[Sequence] NVARCHAR(10) NULL
,Scenario INT NULL -- this will hold 1 for parent trans, 2 for same day, 3 for different day
)
--same structure as the last loops sort of
WHILE @counter <= @rowCount
BEGIN
SELECT @loopRowCount =
COUNT([Sequence])
FROM #INSIDELOOP
WHERE OGTrans IN (SELECT OGTrans FROM #INSIDELOOP_OGROWS WHERE theRow = @counter)
SET @loopCounter = 1
WHILE @loopCounter <= @loopRowCount
BEGIN
IF @loopCounter = 1 -- first row of the set is the original INSERT transaction
BEGIN
INSERT INTO #SECONDINSIDELOOP (transnumber,Item,ParentTransQty,OGTransQty,ShiftedTransQty,DifferenceQty,Transdate,Transtime,TypeDescription,OGTrans,[Sequence],Scenario)
SELECT
OG.transnumber
,OG.Item
,OG.ParentTransQty
,OG.OGTransQty
,OG.ShiftedTransQty
,OG.DifferenceQty
,OG.Transdate
,OG.Transtime
,OG.TypeDescription
,OG.OGTrans
,OG.[Sequence]
,1 AS Scenario
FROM
(
SELECT
transnumber
,Item
,ParentTransQty
,OGTransQty
,ShiftedTransQty
,DifferenceQty
,Transdate
,Transtime
,TypeDescription
,OGTrans
,[Sequence]
FROM #INSIDELOOP_OGROWS
WHERE theRow = @counter
) AS OG
SELECT @currentTransNo = transnumber FROM #INSIDELOOP_OGROWS WHERE theRow = @counter
END
ELSE
--IF @loopCounter = @loopRowCount AND @loopCounter > 1 -- get the last one
BEGIN
INSERT INTO #SECONDINSIDELOOP (transnumber,Item,ParentTransQty,OGTransQty,ShiftedTransQty,DifferenceQty,Transdate,Transtime,TypeDescription,OGTrans,[Sequence],Scenario)
SELECT
XTRAN.transnumber
,XTRAN.Item
,XTRAN.ParentTransQty
,XTRAN.OGTransQty
,XTRAN.ShiftedTransQty
,XTRAN.DifferenceQty
,XTRAN.Transdate
,XTRAN.Transtime
,XTRAN.TypeDescription
,XTRAN.OGTrans
,XTRAN.[Sequence]
,CASE
WHEN FORMAT(OG.Transdate,'yyyy-MM-dd') = FORMAT(XTRAN.Transdate,'yyyy-MM-dd')
THEN 2
ELSE 3 END AS Scenario
FROM
(
SELECT
transnumber
,Item
,ParentTransQty
,OGTransQty
,ShiftedTransQty
,DifferenceQty
,Transdate
,Transtime
,TypeDescription
,OGTrans
,[Sequence]
FROM #INSIDELOOP
WHERE OGTrans = @currentTransNo AND [Sequence] = 'OG'
) AS OG LEFT OUTER JOIN
(
SELECT
transnumber
,Item
,ParentTransQty
,OGTransQty
,ShiftedTransQty
,DifferenceQty
,Transdate
,Transtime
,TypeDescription
,OGTrans
,[Sequence]
FROM #INSIDELOOP
) AS XTRAN ON OG.OGTrans = XTRAN.OGTrans AND XTRAN.[Sequence] = CAST(@loopCounter - 1 AS NVARCHAR(MAX))
END
SET @loopCounter += 1
END
SET @counter += 1
END
-- ok, we have to filter out RECVE transactions....and I think the easiest
-- way to do that would be to just filter them and their associated XTRANs
-- all out at the end. So get the unique RECVE transnumbers to use later
-- to filter out.
SELECT *
INTO #JUSTRECVE
FROM
(
SELECT DISTINCT transnumber
FROM #WHOLEMONTH
WHERE TypeDescription = 'RECVE'
) AS justrecve
-- And now delete the RECVE trans and their
-- associated XTRANS from the looping stuff we just did
DELETE FROM #SECONDINSIDELOOP
WHERE OGTrans IN (SELECT transnumber FROM #JUSTRECVE)
--================================
-- Get the pertinent item info
--================================
SELECT *
INTO #THEITEMS
FROM
(
SELECT DISTINCT Item
FROM #YESTERDAY AS gettingtheitems
) AS theitems
-- now make an index
IF EXISTS
(
SELECT name
FROM sys.indexes
WHERE name = N'IX_THEITEMS'
)
DROP INDEX IX_THEITEMS ON #THEITEMS
CREATE NONCLUSTERED INDEX IX_THEITEMS
ON #THEITEMS (Item)
SELECT *
INTO #INV
FROM
(
SELECT
ItemNumber
,Description2
,Manufacturer
,MfrNumber
,UDFREDACTEDPartReference
FROM REDACTED_CLOUD_01.CM01.dbo.INVENTRY AS INVENTRY
WHERE ItemNumber IN (SELECT Item FROM #THEITEMS)
) AS inv
--======================================
-- Get the pertinent STATION info
--=======================================
SELECT *
INTO #THECRIBBINS
FROM
(
SELECT DISTINCT CribBin
FROM #YESTERDAY AS gettingthecribbins
) AS thecribbins
-- now make an index
IF EXISTS
(
SELECT name
FROM sys.indexes
WHERE name = N'IX_THECRIBBINS'
)
DROP INDEX IX_THECRIBBINS ON #THECRIBBINS
CREATE NONCLUSTERED INDEX IX_THECRIBBINS
ON #THECRIBBINS (CribBin)
SELECT *
INTO #STA
FROM
(
SELECT
CribBin
,Crib
,Bin
,Item
,Consignment
FROM REDACTED_CLOUD_01.CM01.dbo.STATION AS STATION
WHERE CribBin IN (SELECT CribBin FROM #THECRIBBINS)
) AS sta
--======================================
-- Get the pertinent EMPLOYEE info
--=======================================
SELECT *
INTO #EMPLOYEENAME
FROM
(
SELECT DISTINCT employee AS empid
FROM #YESTERDAY AS gettingthename
) AS employeename
-- now make an index
IF EXISTS
(
SELECT name
FROM sys.indexes
WHERE name = N'IX_THENAME'
)
DROP INDEX IX_THENAME ON #EMPLOYEENAME
CREATE NONCLUSTERED INDEX IX_THENAME
ON #EMPLOYEENAME (empid)
SELECT *
INTO #EMP
FROM
(
SELECT
ID
,LastName
,FirstName
,User1
FROM REDACTED_CLOUD_01.CM01.dbo.EMPLOYEE AS EMPLOYEE
WHERE ID IN (SELECT empid FROM #EMPLOYEENAME)
) AS emp
--===================================
-- Now put it together I suppose
--===================================
SELECT *
INTO #CHARGEOUTINTERFACE
FROM
(
SELECT
[COMPANY]
,[CHARGED_QTY]
,[WAREHOUSE]
,[BIN]
,[DEPARTMENT]
,[CHARGED_DATE]
,[REDACTED_PART_NUMBER]
,[OPERATOR_NAME]
,[CREATION_DATETIME]
,[TRANSACTION_ID]
,[TRANSACTION_TYPE]
,[CONSIGNMENT]
FROM
(
SELECT
'REDACTED' AS [COMPANY]
-- ok, need some logic to make it so we
-- report the DIFFERENCE in the original
-- value compared to the XTRAN
,CASE
WHEN YEST.transnumber IN (SELECT transnumber FROM #SECONDINSIDELOOP)
THEN
CASE
WHEN XTRANSORTED.Scenario = 1 THEN XTRANSORTED.ShiftedTransQty
ELSE XTRANSORTED.DifferenceQty
END
ELSE YEST.quantity
END AS [CHARGED_QTY]
,CASE WHEN STA.Crib = 3605 THEN 'JAN' ELSE 'MRO' END AS [WAREHOUSE]
,STA.Bin AS [BIN]
,CASE
WHEN (YEST.TypeDescription = 'ADJUS' OR YEST.TypeDescription = 'COUNT') THEN 'REDACTED'
WHEN YEST.User1 IS NULL THEN EMP.User1
WHEN YEST.User1 = '' THEN EMP.User1
ELSE YEST.User1
END AS [DEPARTMENT]
,FORMAT(CAST(YEST.Transdate AS DATE), 'yyyy-MM-dd') AS [CHARGED_DATE]
,INV.UDFREDACTEDPartReference AS [REDACTED_PART_NUMBER]
,UPPER(EMP.LastName) AS [OPERATOR_NAME]
,FORMAT(CAST(GETDATE() AS DATE), 'yyyy-MM-dd') AS [CREATION_DATETIME]
,CASE WHEN YEST.TypeDescription = 'XTRAN' THEN YEST.BatchId ELSE YEST.transnumber END AS [TRANSACTION_ID]
,CASE
WHEN YEST.TypeDescription = 'XTRAN' THEN 'U'
WHEN YEST.TypeDescription = 'ISSUE' THEN 'I'
WHEN YEST.TypeDescription = 'COUNT' THEN 'I'
WHEN YEST.TypeDescription = 'ADJUS' THEN 'I'
WHEN YEST.TypeDescription = 'CANCL' THEN 'D'
ELSE ''
END AS [TRANSACTION_TYPE]
,STA.Consignment AS [CONSIGNMENT]
FROM
#YESTERDAY AS YEST INNER JOIN
#INV AS INV ON YEST.Item = INV.ItemNumber INNER JOIN
#STA AS STA ON YEST.CribBin = STA.CribBin INNER JOIN
#EMP AS EMP ON YEST.employee = EMP.ID LEFT OUTER JOIN
#SECONDINSIDELOOP AS XTRANSORTED ON YEST.transnumber = XTRANSORTED.transnumber
) AS blah
WHERE
--case statement for a where clause?
CASE WHEN TRANSACTION_TYPE = 'U' AND CHARGED_QTY = 0 THEN 1 ELSE 0 END = 0 AND WAREHOUSE <> 'JAN'
) AS chargeoutinterface
-- now we remove any rows with anything to do with
-- any RECVE transactions...pretty sure we already
-- got them, but for good measure
DELETE FROM #CHARGEOUTINTERFACE
WHERE TRANSACTION_ID IN (SELECT transnumber FROM #JUSTRECVE)
SELECT *
FROM #CHARGEOUTINTERFACE
END
A batch job scheduled in Windows Task Scheduler would run this daily to output a csv file that would be fed to a Bash script running on a Debian Linux VM to deposit the file on the customer's FTP server, along with its brother, the ReceiveInterface which followed the same general format.