is there way to apply row updates without looping - sql

i would like to pay for different invoices using different credits i have.
drop table #InvoicesWithBalances
drop table #AvailableCredits
create table #InvoicesWithBalances
(
InvoiceKey decimal(18,0) not null,
APBalance decimal(18,6) null,
BalanceAfterCreditApplied decimal(18,6) null,
)
create table #AvailableCredits
(
credit_id int identity(1,1),
StartingBalance decimal(18,6) null,
CurrentBalance decimal(18,6) null,
)
insert into #InvoicesWithBalances values (5452, 13744.080000, 13744.080000)
insert into #InvoicesWithBalances values (7056, 13744.080000, 13744.080000)
insert into #InvoicesWithBalances values (7438, 500.000000, 500.000000 )
insert into #AvailableCredits values ( -13744.080000, -13744.080000)
insert into #AvailableCredits values ( -13700.080000, -13700.080000)
insert into #AvailableCredits values ( -500.000000, -500.000000)
insert into #AvailableCredits values ( -500.000000, -500.000000)
select * from #InvoicesWithBalances
select * from #AvailableCredits
If I was doing a looping solution I would take the largest credit and start applying it to the invoices in order of largest to smallest until the balance of the credit is zero, then I would move on to the next to the next credit until I had no credits and no invoices left.
In the example below the first 2 credits should be fully used. The third credit should be partially used and the last credit should go untouched
Any advice?

I have tried to simulate your example here:
create table InvoicesWithBalances
(
InvoiceKey int not null,
APBalance int null,
BalanceAfterCreditApplied int null,
);
create table AvailableCredits
(
credit_id int identity(1,1),
StartingBalance int null,
CurrentBalance int null,
);
insert into InvoicesWithBalances values (5452, 13744, 13744);
insert into InvoicesWithBalances values (7056, 13744, 13744);
insert into InvoicesWithBalances values (7438, 500, 500);
insert into AvailableCredits values ( -13744, -13744);
insert into AvailableCredits values ( -13700, -13700);
insert into AvailableCredits values ( -500, -500);
insert into AvailableCredits values ( -500, -500);
create table #invoice (invoice_row_num int, InvoiceKey int, APBalance int, BalanceAfterCreditApplied int);
insert into #invoice
select ROW_NUMBER() OVER (ORDER BY APBalance desc) as row_num, InvoiceKey, APBalance, BalanceAfterCreditApplied FROM InvoicesWithBalances;
create table #credits (credit_row_num int, StartingBalance int, CurrentBalance int);
insert into #credits
select ROW_NUMBER() OVER (ORDER BY StartingBalance asc) as row_num, StartingBalance, CurrentBalance FROM AvailableCredits;
create table #invoice_credit_list (invoice_credit_row_num int, init_invoice int, init_credit int);
if ((select max(invoice_row_num) from #invoice) > (select max(credit_row_num) from #credits))
insert into #invoice_credit_list
select i.invoice_row_num , i.APBalance, (-isnull(c.StartingBalance,0)) from
#invoice i
left join
#credits c
on
i.invoice_row_num = c.credit_row_num;
else
insert into #invoice_credit_list
select c.credit_row_num, isnull(i.APBalance,0), (-c.StartingBalance) from
#credits c
left join
#invoice i
on
i.invoice_row_num = c.credit_row_num;
with cte as
(
select
invoice_credit_row_num,
init_invoice,
init_credit,
case when init_invoice >= init_credit then
init_invoice - init_credit
else
0
end as 'invoice_remaining',
case when init_credit >= init_invoice then
init_credit - init_invoice
else
0
end as 'credit_remaining'
from
#invoice_credit_list i
where
i.invoice_credit_row_num = 1
UNION ALL
select
i.invoice_credit_row_num,
i.init_invoice + cte.invoice_remaining as 'init_invoice',
i.init_credit + cte.credit_remaining as 'init credit',
case when (i.init_invoice + cte.invoice_remaining) >= (i.init_credit + cte.credit_remaining ) then
(i.init_invoice + cte.invoice_remaining) - (i.init_credit + cte.credit_remaining )
else
0
end as 'invoice_remaining',
case when (i.init_credit + cte.credit_remaining) >= (i.init_invoice + cte.invoice_remaining) then
(i.init_credit + cte.credit_remaining) - (i.init_invoice + cte.invoice_remaining)
else
0
end as 'credit_remaining'
from
#invoice_credit_list i
inner join
cte
ON
i.invoice_credit_row_num - 1 = cte.invoice_credit_row_num
AND
i.invoice_credit_row_num > 1
)
select * from cte;
and you can also find this simulation with output here: https://rextester.com/SJYGV76640
The 'cte' table in the simulation will give you all the details.
Eventhough, this is now done in db side, I am not sure of its performance. So, please compare and evaluate its performance.
Note:
if this is performing faster, well and good. But, at most, don't opt for loops in T-SQL.
If this is not performing better, go for loops in any other programming language like C#, VB,.. if that is possible.
If no other option works for you, go for loops in T-SQL. But, with increasing data, I am not sure how the server will react :(
Hope this helps you :)

Related

How to get the Values of recently inserted columns from Temporary Table?

I am not able to use the recently inserted Quantity value of #ACCT table in the Select statement to be used like
ser.ServiceRate * Quantity
Every time I get the ERROR
Cannot insert the value NULL into column 'Amount'
I am just a beginner so any pointers to solve this would help.
DECLARE #MinReservationId INT = (SELECT MIN(f.ReservationId) FROM dbo.Reservation AS f)
DECLARE #MaxReservationId INT = (SELECT MAX(f.ReservationId) FROM dbo.Reservation AS f)
DECLARE #QuantityNew INT
WHILE #MinReservationId <= #MaxReservationId
BEGIN
CREATE TABLE #Acct
(
ServiceId INT,
Quantity INT --> I WANT THIS VALUE TO BE USED BELOW
)
INSERT INTO dbo.[Transaction]
(
ReservationId,
ServiceId,
Rate,
Quantity,
Amount
)
OUTPUT inserted.ServiceId,Inserted.Quantity
INTO #Acct
(
ServiceId,
Quantity
)
SELECT
#MinReservationId,
ser.ServiceId,
ser.ServiceRate,
ABS(CHECKSUM(NEWID())%3) + 1,
ser.ServiceRate * (SELECT acc.Quantity from #Acct as acc) -> QUANTITY from #ACCT should be used here
FROM dbo.[Service] AS ser
SELECT #MinReservationId=#MinReservationId+1
Drop table #Acct
END
You can use a CTE in order to capture the NEWID() value created for every record of table dbo.[Service]. Then use this CTE to do the INSERT:
;WITH ToInsert AS
(
SELECT ServiceId ,
ServiceRate,
ABS(CHECKSUM(NEWID())%3) + 1 AS Quantity
FROM dbo.[Service]
)
INSERT INTO dbo.[Transaction]
(
ReservationId,
ServiceId,
Rate,
Quantity,
Amount
)
SELECT #MinReservationId,
ServiceId,
ServiceRate,
Quantity,
ServiceRate * Quantity
FROM ToInsert

Replace cursors with queries

Let's say I have a booking covering 6 hours and 3 discounts covering 2 hours each. I want to split my booking into 3 parts so I can allocate 2 hours per discount.
It would return something like this:
BookingId 1 | DiscountId 1 | Qty 2
BookingId 1 | DiscountId 2 | Qty 2
BookingId 1 | DiscountId 3 | Qty 2
I would then insert those records this into another table.
I'm using an heavily optimized query to determine the number of hours available for each discount. However, I can't find a "good" way to allocate my booking to each discount without using a cursor.
(...)
WHILE ##FETCH_STATUS = 0
BEGIN
IF #RequiredQty = 0
RETURN
IF #RequiredQty <= #AvailableQty
BEGIN
INSERT INTO discount.Usage (DiscountId, BookingId, Quantity)
VALUES (#DiscountId, #BookingId, #RequiredQty)
SET #RequiredQty = 0
END
IF #RequiredQty > #AvailableQty
BEGIN
INSERT INTO discount.Usage (DiscountId, BookingId, Quantity)
VALUES (#DiscountId, #BookingId, #AvailableQty)
SET #RequiredQty -= #AvailableQty
END
FETCH NEXT FROM ecursor INTO #DiscountId, #AvailableQty
END
DEALLOCATE ecursor
I tried building the corresponding query but I can't select and assign variables at the same time. Using a cursor is not really a problem (besides some potential performance issues) but I was just curious to see if with the newest SQL Server we can convert our old cursors to something better?
Thanks,
Seb
You can useCTE RECURSIVE to make a Table.
like this.
DECLARE #BookingId INT = 1;
DECLARE #RequiredQty INT = 2;
DECLARE #Hours INT = 7;
CREATE TABLE #T
(
BookingId INT,
DiscountId INT,
Quantity INT
)
;WITH CTE([Count],[Quantity],Rk) AS
(
SELECT
CASE
WHEN [HOURS] - #RequiredQty > #RequiredQty THEN #RequiredQty
ELSE [HOURS] - #RequiredQty
END ,
T.HOURS,1
FROM
(
SELECT #Hours [HOURS]
) AS T
UNION ALL
SELECT CASE
WHEN CTE.[Quantity] - #RequiredQty > #RequiredQty THEN #RequiredQty
ELSE CTE.[Quantity] - #RequiredQty
END AS [Count],
CTE.[Quantity] - #RequiredQty,
RK + 1
FROM CTE
WHERE CTE.[Quantity] - #RequiredQty > 0
)
INSERT INTO #T(BookingId,DiscountId,Quantity)
SELECT #BookingId,Rk,[Count] FROM CTE
option (maxrecursion 0)
select * from #T
SQLDEMO
This is another approach, but don't know if this code has better performance than cursor.
DECLARE #DiscountStocks TABLE (Id INT IDENTITY(1,1), DiscountId INT, LastQty INT)
INSERT INTO #DiscountStocks (DiscountId, LastQty) VALUES (1, 5)
INSERT INTO #DiscountStocks (DiscountId, LastQty) VALUES (2, 2)
INSERT INTO #DiscountStocks (DiscountId, LastQty) VALUES (3, 1)
DECLARE #DiscountBookings TABLE (Id INT IDENTITY(1,1), DiscountId INT, BookingId INT, Qty INT)
DECLARE #BookingDiscount TABLE (Id INT IDENTITY(1,1), BookingId INT, DiscountId INT, Qty INT)
INSERT INTO #BookingDiscount (BookingId, DiscountId, Qty) VALUES (1, 1, 4)
INSERT INTO #BookingDiscount (BookingId, DiscountId, Qty) VALUES (1, 2, 2)
INSERT INTO #BookingDiscount (BookingId, DiscountId, Qty) VALUES (1, 3, 1)
INSERT INTO #BookingDiscount (BookingId, DiscountId, Qty) VALUES (2, 1, 1)
INSERT INTO #BookingDiscount (BookingId, DiscountId, Qty) VALUES (2, 2, 2)
SELECT BD.Id AS BDId, DS.Id AS DSId, DS.LastQty, BD.Qty
, DS.LastQty - (SELECT SUM(Qty) FROM #BookingDiscount WHERE Id <= BD.Id AND DiscountId = BD.DiscountId) AS QtyAfterSubstract
INTO #LastDiscountStock
FROM #DiscountStocks DS
INNER JOIN #BookingDiscount BD ON DS.DiscountId = BD.DiscountId
ORDER BY BD.Id, DS.Id
INSERT INTO #DiscountBookings (DiscountId, BookingId, Qty)
SELECT DSId, BDId, Qty
FROM #LastDiscountStock
WHERE QtyAfterSubstract >= 0
DROP TABLE #LastDiscountStock
SELECT * FROM #DiscountBookings

SQL stored procedure results solution

I have a stored procedure that I inherited. The goal is for the data in the temp table: #multi_nominees_uf to be joined with the data in #temp_reviewers_UF and assign #temp_reviewers_UF.uf_rev_id to #multi_nominees_uf.application_number where the corresponding uf_rev_id's short_plan does not match the major associated with the appNumber's major .
It is not as simple as doing a JOIN.
The following has to be in place:
short_plan can not match the major(associated with the uf_rev_id)
count of each uf_rev_id can only be in the table a certain number of times (#RevsPerRevieweruf). Also, the uf_rev_id will be in the #temp_reviewers_uf table more than once with a different short_plan, it should only be looking at DISTINCT uf_rev_id when calculating the #RevPerRevieweruf.
The way it is written now, the counts are not consistent. One uf_rev_ID may have 122 records and another may have 50 - each distinct uf_rev_id should have the same count (or very close). I have researched and tried NTILE but I couldn't figure it out.
Any ideas of the best way to accomplish this?? Any input is appreciated.
-----Sample Data -----
CREATE TABLE #mult_nominees_uf(
appnum VARCHAR(8)
,major VARCHAR(8)
,compid INT
);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('00012345','ACT',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('10002343','BBC',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('10002777','BBC',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('10000023','DED',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('23457829','AAR',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('78954321','RRE',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('90002342','ACT',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('11156726','AAR',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('88855593','RRE',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('10000001','DED',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('20000393','ACT',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('11119999','DED',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('78927626','AAR',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('67589393','RRE',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('12453647','AAR',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('00012345','ACT',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('10002343','BBC',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('10002777','BBC',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('10000023','DED`',2);
INSERT INTO #mult_nominees_uf(appnum,major,compid) VALUES ('23457829','AAR',2);
--with this sample data the #RevsPerReviewerUF count would be 4 since A5 is listed twice and we only want distinct values used
CREATE TABLE #Temp_Reviewers_uf(
uf_rev_id VARCHAR(8)
,short_plan VARCHAR(8)
,fac_emplid INTEGER
);
INSERT INTO #Temp_Reviewers_uf(uf_rev_id,short_plan,fac_emplid) VALUES ('A1','ACT',00000012);
INSERT INTO #Temp_Reviewers_uf(uf_rev_id,short_plan,fac_emplid) VALUES ('A2','BBC',00000145);
INSERT INTO #Temp_Reviewers_uf(uf_rev_id,short_plan,fac_emplid) VALUES ('A3','DED',10002934);
INSERT INTO #Temp_Reviewers_uf(uf_rev_id,short_plan,fac_emplid) VALUES ('A5','RRE',90001223);
INSERT INTO #Temp_Reviewers_uf(uf_rev_id,short_plan,fac_emplid) VALUES ('A5','ACT',90001223);
----Stored procedure -
DECLARE #Index INT
DECLARE #Num_nomineesUF INT
DECLARE #Num_reviewersUF INT
DECLARE #Num_reviewersUFDISTINCT INT
DECLARE #Num_reviews INT
DECLARE #Rev_ID nvarchar(25), #Nom_ID varchar(8), #Short_Plan varchar(8), #Major varchar(8)
DECLARE #RevsPerReviewerUF INT
SET #Num_reviews = 4
DECLARE #actualCompID int
DECLARE #UF_Flag INT
DECLARE #InsertNum int
SET #InsertNum = 1
create table #mult_nominees_UF (appNumber varchar(8), Major varchar(8), comp_id INT)
create table #TempNomineeTable (uf_rev_id varchar(8), fac_emplid varchar(9), appNumber varchar(8), Major varchar(8), short_plan varchar(8), comp_id int)
create table #Temp_Reviewers_UF (uf_rev_id varchar(8), short_plan varchar(8), fac_emplid varchar(9)) -- temp table used to hold Nom_IDs already assigned to Rev_IDs
set #actualCompID = 21
-- * * SELECT APPLICATION NUMBER & MAJOR FROM FS_RESULTS TABLE * * * * * --
select appNumber, LEFT(Major, CHARINDEX('-', Major)-1) as Major, comp_id into #Delete_nomineesUF
from FS_Results
where UF='Y'
and comp_id = #actualCompID
and nominated=1;
SET #Num_nomineesUF = ##rowcount; --GET RECORD COUNT
IF (#Num_nomineesUF > 0)
BEGIN
SET #UF_Flag = 1;
END
SET #Index = 1 ; -- reinit variable
WHILE #Index <= 4 BEGIN
if (#UF_Flag > 0)
BEGIN
INSERT into #mult_nominees_uf
select * from #Delete_nomineesUF
END
-- Create temp table for UF Reviewers
select uf_rev_id, short_plan, fac_emplid into #temp_reviewers_UF
from ReviewersID_ShortPlan
where uf_rev_id like 'UF%'
and competition_id = #actualCompID
SET #Num_reviewersUF = ##rowcount
SELECT DISTINCT UF_REV_ID FROM ReviewersID_ShortPlan WHERE UF_REV_ID like 'UF%' AND competition_id = #actualCompID
SET #Num_reviewersUFDistinct = ##rowcount
SET #RevsPerReviewerUF = (#Num_nomineesUF * #Num_reviews) / nullif(#Num_reviewersUFDistinct,0)
WITH Match_NomineesWithReviewers AS(
SELECT DISTINCT
appNumber,
RTRIM(Major) AS Major,
COUNT(1) as rowcnt,
comp_id
FROM #mult_nominees_uf
GROUP BY appNumber,
RTRIM(Major),
comp_id
)
, rownum_matches AS (
SELECT m.appNumber,
m.Major,
t.short_plan,
t.uf_rev_id,
t.fac_emplid,
m.rowcnt,
m.comp_id,
ROW_NUMBER() OVER (PARTITION BY m.appNumber order by newid()) AS rownum
FROM Match_NomineesWithReviewers m
JOIN #temp_reviewers_UF t ON t.short_plan != m.major
GROUP BY m.appNumber, m.Major, t.short_plan,
t.uf_rev_id, t.fac_emplid, m.rowcnt, m.comp_id
HAVING COUNT(t.uf_rev_id) <= #RevsPerRevieweruf
)
INSERT INTO #TempNomineeTable
SELECT uf_rev_id, fac_emplid, appNumber, Major, short_plan, null, 0, null, comp_id FROM rownum_matches rm
WHERE rownum <= rowcnt
group by uf_rev_id, fac_emplid, appNumber, Major, short_plan, comp_id
HAVING COUNT(uf_rev_id) <= #RevsPerRevieweruf

Assign multiple values to Table variable in SQL

DECLARE #ID INT
SET #ID = (select top 1 USER_REQ_JOB_ID
from T8504_USER_REQ_JOB
where JOB_GRP_ID = 160
order by LST_UPDT_TS desc)
SELECT INPUT_PARM_VAL_TX
from TBL_RPT_JOB_INPUT_PARAM
where USER_REQ_JOB_ID = #ID
This returns these results:
USA
USCC
6
7
2
These five records what I get I want to assign to five different variables to use in stored procedure.
I was trying with table variable like this :
declare #CID table (
Region Char(3)
,Segment Char(3)
,MasterContractId int
,ctcid int
,templateid int)
insert into #CID (Region,Segment,MasterContractId,ctcid,templateid)
But how to insert that 5 rows here?
INSERT INTO #CID
select * from
(
select
'Temp' + convert(char(1), row_number() over (order by (select 0))) as columnName,
INPUT_PARM_VAL_TX as Value
from TBL_RPT_JOB_INPUT_PARAM where USER_REQ_JOB_ID = #ID
) d
pivot
(
max(value)
for columnname in (Temp1, Temp2, Temp3, Temp4, Temp5)
) piv;
See if this helps.
Take a look at this fiddle for an example.
Courtesy:
Add row number to this T-SQL query
Efficiently convert rows to columns in sql server
EDIT: The sql adds an extra column to generate row numbers to use it as an extra column, which is pivoted as column heading.
it's really gross, but one way you could probably do it is this (though you'll need to apply it to your case):
http://sqlfiddle.com/#!6/d41d8/21507
declare #table TABLE (value varchar(50))
INSERT INTO #table
VALUES ('first')
INSERT INTO #table
VALUES ('second')
INSERT INTO #table
VALUES (3)
INSERT INTO #table
VALUES (4)
DECLARE #temp TABLE (id int identity(1,1), value varchar(50))
INSERT INTO #temp
SELECT [value]
FROM #table t
SELECT *
FROM #temp
DECLARE #CID TABLE (Region varchar(50), cont varchar(50), another int, andAnother int)
INSERT INTO #CID
(
Region,
cont,
another,
andAnother
)
VALUES
(
(SELECT value FROM #temp WHERE id = 1), -- Region - varchar
(SELECT value FROM #temp WHERE id = 2), -- cont - varchar
(SELECT value FROM #temp WHERE id = 3), -- another - int
(SELECT value FROM #temp WHERE id = 4) -- andAnother - int
)
SELECT * FROM #cid
note that i assumed you're using mssql, you did not specify

Select one records from three tables based on latest date

I have a TransactionMaster table in SQL Server 2012 that has unique TransactionID. The same TransactionID wil be availabe in LowTransaction ,MediumTransaction and HighTransaction tables.
For each TransactionID in TransactionMaster, I need to display one StatusMessage. The StatusMessage may come from any of the 3 tables - based on date formulated from CRTDTEC and CRTTIME columns..
What is the best way in SQL Server 2012 to select the StatusMessage corresponding to latest date?
Note: CRTDTEC Format - YYMMDD and CRTTIME Format - HHMMSS
CODE
DECLARE #TransactionMaster TABLE (TransactionID INT)
DECLARE #LowTransaction TABLE (TransactionID INT, StatusMessage VARCHAR(80), CRTDTEC VARCHAR(8), CRTTIME VARCHAR(6))
DECLARE #MediumTransaction TABLE (TransactionID INT, StatusMessage VARCHAR(80), CRTDTEC VARCHAR(8), CRTTIME VARCHAR(6))
DECLARE #HighTransaction TABLE (TransactionID INT, StatusMessage VARCHAR(80), CRTDTEC VARCHAR(8), CRTTIME VARCHAR(6))
INSERT INTO #TransactionMaster VALUES (1)
INSERT INTO #TransactionMaster VALUES (2)
INSERT INTO #TransactionMaster VALUES (3)
INSERT INTO #LowTransaction VALUES (1,'1 Low','20131213','235959')
INSERT INTO #MediumTransaction VALUES (1,'1','20131213','235900')
INSERT INTO #HighTransaction VALUES (1,'1 High','20111213','235959')
INSERT INTO #LowTransaction VALUES (2,'2 Low','20111213','235959')
INSERT INTO #LowTransaction VALUES (3,'3 Low','20111213','235959')
INSERT INTO #MediumTransaction VALUES (3,'3 Medium','20111213','235959')
INSERT INTO #HighTransaction VALUES (3,'3 High','20140101','235959')
Expected Result
(1,'1 Low','20131213','235959')
(2,'2 Low','20111213','235959')
(3,'3 High','20140101','235959')
The simplest way would probably be
WITH TransConsolidated
AS (SELECT *
FROM #LowTransaction
UNION ALL
SELECT *
FROM #MediumTransaction
UNION ALL
SELECT *
FROM #HighTransaction)
SELECT TM.TransactionID,
CA.*
FROM #TransactionMaster TM
CROSS APPLY (SELECT TOP 1 *
FROM TransConsolidated TC
WHERE TC.TransactionID = TM.TransactionID
ORDER BY CRTDTEC DESC,
CRTTIME DESC) CA
Or another possibility (if there is a covering index ordered by TransactionID on all tables) would be to merge join all four tables involved
;WITH CTE
AS (SELECT TM.TransactionID,
MAX(CA.CRTDTEC + CA.CRTTIME + CA.StatusMessage) AS MaxRow
FROM #TransactionMaster TM
LEFT MERGE JOIN #LowTransaction LT
ON LT.TransactionID = TM.TransactionID
LEFT MERGE JOIN #MediumTransaction MT
ON MT.TransactionID = TM.TransactionID
LEFT MERGE JOIN #HighTransaction HT
ON HT.TransactionID = TM.TransactionID
CROSS APPLY (SELECT LT.*
UNION ALL
SELECT MT.*
UNION ALL
SELECT HT.*) CA
GROUP BY TM.TransactionID)
SELECT TransactionID,
SUBSTRING(MaxRow, 1, 8),
SUBSTRING(MaxRow, 9, 6),
SUBSTRING(MaxRow, 16, 80)
FROM CTE
I guess you could do something like this...
SELECT TransactionID, StatusMessage, CRTDTEC, CRTTIME
FROM
(
SELECT *, rn = ROW_NUMBER() OVER (PARTITION BY TransactionID ORDER BY CRTDTEC DESC)
FROM
(
SELECT * FROM #LowTransaction
UNION ALL
SELECT * FROM #MediumTransaction
UNION ALL
SELECT * FROM #HighTransaction
)q
) q2
WHERE rn = 1
Result Set
TransactionID StatusMessage CRTDTEC CRTTIME
1 1 Low 20131213 235959
2 2 Low 20111213 235959
3 3 High 20140101 235959