TSQL - Display the date which exist in all Model - sql-server

MODEL DateCreated
----------------------
MODEL_1 2017-07-20
MODEL_1 2017-07-19
MODEL_1 2017-06-10
MODEL_1 2017-06-02
MODEL_2 2017-07-18
MODEL_2 2017-07-17
MODEL_2 2017-06-10
MODEL_2 2017-06-02
MODEL_3 2017-07-20
MODEL_3 2017-07-12
MODEL_3 2017-06-10
MODEL_3 2017-06-02
MODEL_3 2017-05-16
Expected result
DateCreated_Exist_In_All_Model
------------------------------
2017-06-10
2017-06-02
This means, only those DateCreated exist in all model will be displayed
Thanks to everyone who willing to help me.

One approach would be to aggregate on the creation date and then compare the count of distinct models appearing on each date against the total number of models appearing in the table.
SELECT
DateCreated AS DateCreated_Exist_In_All_Model
FROM [yourTable]
GROUP BY DateCreated
HAVING COUNT(DISTINCT MODEL) = (SELECT COUNT(DISTINCT MODEL) FROM yourTable)
Note that even though there appear to be only 3 models in your data set, we can make the query more flexible by using a subquery which counts the number of distinct models in the entire table.

DECLARE #Temp table(Model varchar(1000), DateCreated date)
INSERT INTO #Temp
SELECT 'MODEL_1' , '2017-07-20'
UNION ALL
SELECT 'MODEL_1', '2017-07-19'
UNION ALL
SELECT 'MODEL_1', '2017-06-10'
UNION ALL
SELECT 'MODEL_1', '2017-06-02'
UNION ALL
SELECT 'MODEL_2', '2017-07-17'
UNION ALL
SELECT 'MODEL_2', '2017-06-10'
UNION ALL
SELECT 'MODEL_2', '2017-06-02'
UNION ALL
SELECT 'MODEL_3', '2017-07-12'
UNION ALL
SELECT 'MODEL_3 ', '2017-06-10'
UNION ALL
SELECT 'MODEL_3 ', '2017-06-02'
UNION ALL
SELECT 'MODEL_3' , '2017-05-16'
DECLARE #ModelCount int
SELECT #ModelCount = COUNT(distinct Model) from #Temp
SELECT DISTINCT DateCreated FROM (
SELECT
COUNT(MODEL) OVER(PARTITION BY DateCreated) AS Counts, Model,
DateCreated
FROM #Temp) AS D
WHERE D.Counts = #ModelCount
Or
SELECT DateCreated FROM (
SELECT
ROW_NUMBER() OVER(PARTITION BY DateCreated ORDER BY DateCreated) as Rownum,
COUNT(MODEL) OVER(PARTITION BY DateCreated) AS Counts, Model,
DateCreated
FROM #Temp) AS D
WHERE D.Counts = #ModelCount and D.Rownum = 1

Related

SQL Server Window Paging Based on # of Groups

Given the following table structure
Column
Id
Name
DateCreated
with the following data
id
Name
DateCreated
1
Joe
1/13/2021
2
Fred
1/13/2021
3
Bob
1/12/2021
4
Sue
1/12/2021
5
Sally
1/10/2021
6
Alex
1/9/2021
I need SQL that will page over the data based on datecreated. The query should return the top 3 records, and any record which also shares the datecreated of the top 3.
So give the data above, we should get back Joe, Fred and Bob (as the top 3 records) plus Sue since sue has the same date as Bob.
Is there something like ROW_NUMBER that increments for each row where it encounters a different value.
For some context this query is being used to generate an agenda type view, and once we select any date we want to keep all data for that date together.
EDIT
I do have a solution but it smells:
;WITH CTE AS ( SELECT ROW_NUMBER() OVER(ORDER BY DateCreated DESC) RowNum,CAST(DateCreated AS DATE) DateCreated,Name
FROM MyTable),
PAGE AS (SELECT *
FROM CTE
WHERE RowNum<=5)
SELECT *
FROM Page
UNION
SELECT *
FROM CTE
WHERE DateCreated=(SELECT MIN(DateCreated) FROM Page)
I've used a TOP 3 WITH TIES example and a ROW_NUMBER example and a CTE to return four records:
DROP TABLE IF EXISTS #tmp
GO
CREATE TABLE #tmp (
Id INT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
dateCreated DATE
)
GO
INSERT INTO #tmp VALUES
( 1, 'Joe', '13 Jan 2021' ),
( 2, 'Fred', '13 Jan 2021' ),
( 3, 'Bob', '12 Jan 2021' ),
( 4, 'Sue', '12 Jan 2021' ),
( 5, 'Sally', '10 Jan 2021' ),
( 6, 'Alex', '9 Jan 2021' )
GO
-- Gets same result
SELECT TOP 3 WITH TIES *
FROM #tmp t
ORDER BY dateCreated DESC
;WITH cte AS (
SELECT ROW_NUMBER() OVER( ORDER BY dateCreated DESC ) rn, *
FROM #tmp
)
SELECT *
FROM #tmp t
WHERE EXISTS
(
SELECT *
FROM cte c
WHERE rn <=3
AND t.dateCreated = c.dateCreated
)
My results:
As #Charlieface, we only need to replace ROW_NUMBER with DENSE_RANK. So that the ROW_NUMBER will be tied according to the same value.
When we run the query:
SELECT DENSE_RANK () OVER(ORDER BY DateCreated DESC) RowNum,CAST(DateCreated AS DATE) DateCreated,Name
FROM MyTable
The result will show as follows:
So as a result, we can set RowNum<=3 in the query to get the top 3:
;WITH CTE AS ( SELECT DENSE_RANK() OVER(ORDER BY DateCreated DESC) RowNum,CAST(DateCreated AS DATE) DateCreated,Name
FROM MyTable),
PAGE AS (SELECT *
FROM CTE
WHERE RowNum<=3)
SELECT *
FROM Page
UNION
SELECT *
FROM CTE
WHERE DateCreated=(SELECT MIN(DateCreated) FROM Page)
The First one is as yours the second one is as above. The results of the two queries are the same.
Kindly let us know if you need more infomation.

Variable within SQL query

I have this:
SELECT NEWID() as id,
'OwnerReassign' as name,
1 as TypeId,
'MyOrganisation' as OrgName,
'07DA8E53-74BD-459C-AF94-A037897A51E3' as SystemUserId,
0 as StatusId,
GETDATE() as CreatedAt,
'{"EntityName":"account","Ids":["'+CAST(AccountId as varchar(50))+'"],"OwnerId":"0C01C994-1205-E511-988E-26EE4189191B"}' as [Parameters]
FROM Account
WHERE OwnerIdName IN ('John Smith') AND New_AccountType = 1
Within the parameter field is an id (0C01C994-1205-E511-988E-26EE4189191B). Is it possible it could sequentially assign a different id from a list for each row? There are 5 id's in total.
What i'm trying to get to is this result set equally split between the 5 different id's.
Thanks
You can add one more NEWID() in the sub query and handle in the SELECT as below:
SELECT id, [name], TypeId, OrgName, SystemUserId, StatusId, CreatedAt,
'{"EntityName":"account","Ids":["' + AccountId +'"],"OwnerId":"' + ParamId + '"}' as [Parameters]
FROM (
SELECT NEWID() as id,
'OwnerReassign' as name,
1 as TypeId,
'MyOrganisation' as OrgName,
'07DA8E53-74BD-459C-AF94-A037897A51E3' as SystemUserId,
0 as StatusId,
GETDATE() as CreatedAt,
CAST(NEWID() AS VARCHAR (36)) as ParamId,
CAST(AccountId as varchar(50)) as AccountId
FROM Account
WHERE OwnerIdName IN ('John Smith') AND New_AccountType = 1
) A
You can use something like the following. Basically, use a row number for both your IDs and your data table to update, then do a MOD (%) operation with the amount of ID's you want to assign, so your data table to update is split into N groups. Then use that group ID to assign each ID.
IF OBJECT_ID('tempdb..#IDsToAssign') IS NOT NULL
DROP TABLE #IDsToAssign
CREATE TABLE #IDsToAssign (
IDToAssign VARCHAR(100))
-- 3 IDs example
INSERT INTO #IDsToAssign (
IDToAssign)
SELECT IDToAssign = NEWID()
UNION ALL
SELECT IDToAssign = NEWID()
UNION ALL
SELECT IDToAssign = NEWID()
DECLARE #AmountIDsToAssign INT = (SELECT COUNT(1) FROM #IDsToAssign)
IF OBJECT_ID('tempdb..#Account') IS NOT NULL
DROP TABLE #Account
CREATE TABLE #Account (
PrimaryKey INT PRIMARY KEY,
AssignedID VARCHAR(100))
-- 10 Rows example
INSERT INTO #Account (
PrimaryKey)
VALUES
(100),
(200),
(351),
(154),
(194),
(345),
(788),
(127),
(124),
(14)
;WITH DataRowNumber AS
(
SELECT
A.*,
RowNumber = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM
#Account AS A
),
IDsRowNumbers AS
(
SELECT
D.IDToAssign,
RowNumber = ROW_NUMBER() OVER (ORDER BY D.IDToAssign)
FROM
#IDsToAssign AS D
),
NewIDAssignation AS
(
SELECT
R.*,
IDRowNumberAssignation = (R.RowNumber % #AmountIDsToAssign) + 1
FROM
DataRowNumber AS R
)
UPDATE A SET
AssignedID = R.IDToAssign
FROM
NewIDAssignation AS N
INNER JOIN IDsRowNumbers AS R ON N.IDRowNumberAssignation = R.RowNumber
INNER JOIN #Account AS A ON N.PrimaryKey = A.PrimaryKey
SELECT
*
FROM
#Account AS A
ORDER BY
A.AssignedID
/* Results:
PrimaryKey AssignedID
----------- ------------------------------------
124 1CC7F0F1-7EDE-4F7F-B0A3-739D74A62390
194 1CC7F0F1-7EDE-4F7F-B0A3-739D74A62390
351 1CC7F0F1-7EDE-4F7F-B0A3-739D74A62390
788 2A58A573-EDCB-428E-A87A-6BFCED265A9C
200 2A58A573-EDCB-428E-A87A-6BFCED265A9C
127 2A58A573-EDCB-428E-A87A-6BFCED265A9C
14 2A58A573-EDCB-428E-A87A-6BFCED265A9C
100 FD8036DA-0E15-453E-8A59-FA3C2BDB8FB1
154 FD8036DA-0E15-453E-8A59-FA3C2BDB8FB1
345 FD8036DA-0E15-453E-8A59-FA3C2BDB8FB1
*/
The ordering of the ROW_NUMBER() function will determine how ID's are assigned.
You could potentially do this by using the ROW_NUMBER() field in a subquery; for example:
SELECT NEWID() as id, 'OwnerReassign' as name, 1 as TypeId,
'MyOrganisation' as OrgName,
'07DA8E53-74BD-459C-AF94-A037897A51E3' as SystemUserId,
0 as StatusId, GETDATE() as CreatedAt,
case B / ##ROWCOUNT
when 0 then '0C01C994-1205-E511-988E-26EE4189191B'
when 1 then '12345677-1205-E511-988E-26EE4189191B'
when 2 then '66666666-1205-E511-988E-26EE4189191B'
etc...
end
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY A.Id)
FROM Account A
WHERE OwnerIdName IN ('John Smith') AND New_AccountType = 1
) AS B
If you want the system to pick those values then you could put then in their own temporary table, too.

How to find rows that are not shared between two queries from the same source table

I have a CTE that that gives me the result of 760 rows. And I have another SELECT statement that gives me 722 rows.
I want to see which records exist in CTE that are not exists in SELECT statement.
I'm using NOT EXISTS statement, but for some reason it doesnt give me any result. I also tried NOT IN - but the same...no records.
;WITH Cte_Policies AS
(
SELECT
PolicyNumber,
ControlNo,
EffectiveDate,
ExpirationDate,
ProducerName,
SUM(BOUND_Premium) as NetWrittenPremium
FROM CatalyticWindEQ
WHERE EffectiveDate >= '05-01-2016' AND EffectiveDate <= EOMONTH(GETDATE())
AND LineName = 'Earthquake' AND Underwriter <> 'Batcheller, Jerry' AND PolicyNumber IS NOT NULL
GROUP BY
ProducerName,
EffectiveDate
,ExpirationDate ,PolicyNumber, ControlNo
)
SELECT PolicyNumber,
ControlNo,
YEAR(EffectiveDate) as PolicyEffectiveYear,
MONTH(EffectiveDate) as PolicyEffectiveMonth,
NetWrittenPremium,
ProducerName as Producer
FROM
Cte_Policies
where
NOT EXISTS
(
SELECT
PolicyNumber
FROM CatalyticWindEQ eq
WHERE EffectiveDate>='05-01-2016' AND EffectiveDate <= EOMONTH(GETDATE()) AND LineName = 'Earthquake' AND Underwriter <> 'Batcheller, Jerry'
AND PolicyNumber IS NOT NULL
and eq.PolicyNumber=Cte_Policies.PolicyNumber
GROUP BY PolicyNumber
)
The result from CTE only with 760 rows looks like this:
And the result from SELECT statement that gives 722 rows looks like this:
I've done this"
; with CTE as
(
SELECT
PolicyNumber,
ControlNo,
EffectiveDate,
ExpirationDate,
ProducerName,
SUM(BOUND_Premium) as NetWrittenPremium
FROM CatalyticWindEQ
WHERE EffectiveDate >= '05-01-2016' AND EffectiveDate <= EOMONTH(GETDATE())
AND LineName = 'Earthquake' AND Underwriter <> 'Batcheller, Jerry' AND PolicyNumber IS NOT NULL
GROUP BY
ProducerName,
EffectiveDate
,ExpirationDate ,PolicyNumber, ControlNo
)
SELECT PolicyNumber,
min(tag) as min_tag,
max(tag) as max_tag
FROM
(
SELECT PolicyNumber, 1 as tag FROM CTE
UNION ALL
SELECT PolicyNumber, 2 as tag FROM CatalyticWindEQ
) U
GROUP BY PolicyNumber
HAVING COUNT(*)=1
And now I have 888 rows with min_tag = 2 and max_tag=2. Does it mean each policy number is duplicated in my source table?
The basic strategy is to select both datasets (lists of PolicyNumber), collect them using union all, and find the unique items in the combination.
; with CTE as ( ... ) -- the CTE from above
Select PolicyNumber, min(tag) as min_tag, max(tag) as max_tag from (
select PolicyNumber, 1 as tag from CTE
union all
select PolicyNumber, 2 as tag from CatalyticWindEQ -- the source you're matching
) U
Group by PolicyNumber
Having count(*) =1 -- equivalently, having min(tag) = max(tag)
Rows having max(tag) = 1 are only in the CTE.
you can use the full outer join to flag the differences, after putting your second query inside another cte, say cte2, you can try something like this:
select
a.PolicyNumber,
a.ControlNo,
a.YEAR(EffectiveDate) as PolicyEffectiveYear,
a.MONTH(EffectiveDate) as PolicyEffectiveMonth,
a.NetWrittenPremium,
a.ProducerName as Producer,
b.PolicyNumber
from Cte_Policies as a
full outer join cte2 as b ON b.PolicyNumber=a.PolicyNumber
where
a.PolicyNumber is null -- will show records NOT in cte.
OR b.PolicyNumber is null -- Will show records NOT in cte2.

Trying to pivot event dates in t-sql without using a cursor

I have the following table:
What I want is to get to this:
EventTypeId 1 and 3 are valid start events and EventTypeId of 2 is the only valid end event.
I have tried to do a pivot, but I don't believe a pivot will get me the multiple events for a person in the result set.
SELECT PersonId, [1],[3],[2]
FROM
(
SELECT PersonId, EventTypeId, EventDate
from #PersonEvent
) as SourceTable
PIVOT
(
count(EventDate) FOR EventTypeId
IN ([1],[3],[2])
) as PivotTable
Select PersonID,
Min(Case WHEN EventTypeId IN (1,3) THEN EventDate END) as StartDate,
Min(Case WHEN EventTypeId IN (2) THEN EventDate END) as EndDate
FROM #PersonEvent
group by personid
I can do a cursor, but my original table is over 90,000 rows, and this is to be for a report, so I don't think I can use that option. Any other thoughts that I might be missing?
Assuming the table is called [dbo].[PersonEventRecords] this will work...
With StartEvents As
(
Select *
From [dbo].[PersonEventRecords]
Where EventTypeId In (1,3)
), EndEvents As
(
Select *
From [dbo].[PersonEventRecords]
Where EventTypeId In (2)
)
Select IsNull(se.PersonId,ee.PersonId) As PersonId,
se.EventTypeId As StartEventTypeId,
se.EventDate As StartEventDate,
ee.EventTypeId As EndEventTypeId,
ee.EventDate As EndEventDate
From StartEvents se
Full Outer Join EndEvents ee
On se.PersonId = ee.PersonId
And se.EventSequence = ee.EventSequence - 1
Order By IsNull(se.PersonId,ee.PersonId),
IsNull(se.EventDate,ee.EventDate);
/**** TEST DATA ****/
If Object_ID('[dbo].[PersonEventRecords]') Is Not Null
Drop Table [dbo].[PersonEventRecords];
Create Table [dbo].[PersonEventRecords]
(
PersonId Int,
EventTypeId Int,
EventDate Date,
EventSequence Int
);
Insert [dbo].[PersonEventRecords]
Select 1,1,'2012-10-13',1
Union All
Select 1,2,'2012-10-20',2
Union All
Select 1,1,'2012-11-01',3
Union All
Select 1,2,'2012-11-13',4
Union All
Select 2,1,'2012-05-07',1
Union All
Select 2,2,'2012-06-01',2
Union All
Select 2,3,'2012-07-01',3
Union All
Select 2,2,'2012-08-30',4
Union All
Select 3,2,'2012-04-05',1
Union All
Select 3,1,'2012-05-04',2
Union All
Select 3,2,'2012-05-24',3
Union All
Select 4,1,'2013-01-03',1
Union All
Select 4,1,'2013-02-20',2
Union All
Select 4,2,'2013-03-20',3;
Try this
SELECT E1.PersonId, E1.EventTypeId, E1.EventDate, E2.EventTypeId, E2.EventDate
FROM PersonEvent AS E1
OUTER APPLY(
SELECT TOP 1 PersonEvent.EventTypeId, PersonEvent.EventDate
FROM PersonEvent
WHERE PersonEvent.PersonId = E1.PersonId
AND PersonEvent.EventSequence = E1.EventSequence + 1
AND PersonEvent.EventTypeId = 2
) AS E2
WHERE E1.EventTypeId = 1 OR E1.EventTypeId = 3
UNION
SELECT E3.PersonId, NULL, NULL, E3.EventTypeId, E3.EventDate
FROM PersonEvent E3
WHERE E3.EventTypeId = 2
AND NOT EXISTS(
SELECT *
FROM PersonEvent
WHERE PersonEvent.PersonId = E3.PersonId
AND PersonEvent.EventSequence = E3.EventSequence - 1)
It is not completely clear how do you want the result to be ordered – add order as needed.

Pivoting the employee column

I have a table like so.
I need the final result show only one record for each order (essentially combine the suborders). Only sum up the revenue for distinct suborders (for order 0935744, sum up 575.04 + 31.68). An order can have a maximum of 2 employees
Final result should be like this:
order totalrevenue employee1 employee2
0813700 258.57 CREW NULL
0935744 606.72 95liv 95nat
I've tried using row_number and doing some joins but I've had no luck.
Sample code
SELECT N'0813700' AS [OrderNum], N'1077980' AS [SubOrder], N'CREW' AS [employeeid], N'258.57' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1257060' AS [SubOrder], N'95LIV' AS [employeeid], N'575.04' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1342944' AS [SubOrder], N'95LIV' AS [employeeid], N'31.68' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1257060' AS [SubOrder], N'95NAT' AS [employeeid], N'575.04' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1342944' AS [SubOrder], N'95NAT' AS [employeeid], N'31.68' AS [revenue]
this should give the result you are looking for:
create table #temp
(
ordernum int,
suborder int,
employeeid varchar(50),
revenue money
)
insert into #temp values(0813700, 1077980, 'CREW', 258.57)
insert into #temp values(0935744, 1257060, '95LIV', 575.04)
insert into #temp values(0935744, 1342944, '95LIV', 31.68)
insert into #temp values(0935744, 1257060, '95NAT', 575.04)
insert into #temp values(0935744, 1342944, '95NAT', 31.68)
select ordernum
, sum(revenueperorder) as total
, employee1
, case when employee1 = employee2 then null else employee2 end as employee2
from
(
select ordernum
, revenue as revenueperorder
, min(employeeid) as employee1
, max(employeeid) as employee2
from #temp
group by ordernum, revenue
) x
group by ordernum, employee1, employee2
drop table #temp
Results:
813700 258.57 CREW NULL
935744 606.72 95LIV 95NAT
Answers so far would require a hard coded pivot with employee1 & 2 defined as pivot entities, of couse, if your data is dynamic i'd imagine you'll have a varying number of employees (and thus would need a varying number of columns)? If so, i'd suggest you adopt a hybrid dynamic SQL / Pivot example such as:
Pivot Table and Concatenate Columns
or this:
PIVOT in sql 2005
DECLARE #SubOrder TABLE
(
OrderNum INT NOT NULL,
SubOrder INT NOT NULL,
EmployeeID NVARCHAR(50) NOT NULL,
Revenue NUMERIC(10, 2) NOT NULL
);
INSERT #SubOrder (OrderNum, SubOrder, EmployeeID, Revenue)
SELECT N'0813700' AS [OrderNum], N'1077980' AS [SubOrder], N'CREW' AS [employeeid], N'258.57' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1257060' AS [SubOrder], N'95LIV' AS [employeeid], N'575.04' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1342944' AS [SubOrder], N'95LIV' AS [employeeid], N'31.68' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1257060' AS [SubOrder], N'95NAT' AS [employeeid], N'575.04' AS [revenue] UNION ALL
SELECT N'0935744' AS [OrderNum], N'1342944' AS [SubOrder], N'95NAT' AS [employeeid], N'31.68' AS [revenue];
SELECT pvt.OrderNum,
pvt.TotalRevenue,
pvt.[1] AS Emp1,
pvt.[2] AS Emp2
FROM
(
SELECT dt.OrderNum,
dt.EmployeeID,
DENSE_RANK() OVER(PARTITION BY dt.OrderNum ORDER BY dt.EmployeeID) AS Rnk,
SUM(dt.Revenue) OVER(PARTITION BY dt.OrderNum) AS TotalRevenue
FROM
(
SELECT so.OrderNum,
so.EmployeeID,
ROW_NUMBER() OVER(PARTITION BY so.OrderNum, so.SubOrder ORDER BY ##SPID) AS RowNum,
so.Revenue
FROM #SubOrder so
) dt
WHERE dt.RowNum = 1
) src
PIVOT ( MAX(src.EmployeeID) FOR src.Rnk IN ([1], [2]) ) pvt
Results:
OrderNum TotalRevenue Emp1 Emp2
-------- ------------ ------ -----
813700 258.57 CREW NULL
935744 606.72 95LIV 95NAT
Intermediate results (...) src:
OrderNum EmployeeID Rnk TotalRevenue
-------- ---------- --- ------------
813700 CREW 1 258.57
935744 95LIV 1 606.72
935744 95NAT 2 606.72
Intermediate results (...) dt:
OrderNum EmployeeID RowNum Revenue
-------- ---------- ------ -------
813700 CREW 1 258.57
935744 95LIV 1 575.04
935744 95NAT 2 575.04
935744 95NAT 1 31.68
935744 95LIV 2 31.68
How about this? (Revised after comment from OP)
Assumptions:
No more than two employees per order.
One employee per sub-order (as in the example)
Revenue for a sub order is consistently duplicated on rows for the suborder (per example)
Code Example
select order, sum(revenue) as totalrevenue, max(employee1) as employee1,
case
when max(employee1) = max(employee2) then null
else max(employee2)
end as employee2
from (
select order, suborder, max(revenue) as revenue, max(employeeid)
from orders
group by order, suborder
) SubOrderTotal
group by order
Generally I would not recommend the rigid transform to two employees or the duplication of suborder revenue. Making such rigid assumptions often leads to bugs when dealing with real world data. But, I don't know your data.

Resources