Test (90%) and Control (10%) split at retailer level and also segment level in SQL. How to do it?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
Business Context:
To put it simply, I would like to split my data set in to test and control and run some campaigns in the future. But there seems to be lot of complexities involved when I try to split it.
Data:
RetailerCode CID Segment
A6005 13SVC15 High
A6005 19VDE1F Low
A6005 1B3BD1F Medium
A6005 1B3HB48 Medium
A6005 1B3HB49 Low
A9006 1B3HB40 High
A9006 1B3HB41 High
A9006 1B3HB43 Low
A9006 1B3HB46 Medium
I have a master table like this which has the list of customers and their retailers, segment etc. (it has more than 30 columns, but I don’t want to show everything here). I would like to split this data set by adding a column, lets say “test_control” which will tell us whether particular row is test or control category. I can split this randomly but I need to follow the following rules,
- If a customer is tied to two or more retailers, then he should be in control group
- Each retailer will be provided with list of customers to target for the campaigns and the retailer will run the campaign. Here,
o Test-Control split should be done at Retailer level and then at segment level. For example, For each retailer
10% of their High customers to control and remaining 90% of their high customers to test.
10% of their Medium customers to control and remaining 90% of their Medium customers to test
10% of their Low customers to control and remaining 90% of their Low customers to test.
I can share the query that I wrote but that will totally confuse you guys 😊
But this is the high level approach that I followed
- Took out the records from the main table where customer occurred more than once and added a “test_control” column with “control” in it and saved it in a separate temp table 1
- Took out the records from the main table where customer occurred only once and saved it in a temp table 2
- On table 2, I tried to split to 10% (control) and 90% (test)
- Used union all to merge table 1 and table 2. But the ouput is totally wrong
Expected output

As you can see it split 10% and 90% at segment level as well
Please someone help me with this. Been working on this for past couple of days but no luck
Thanks in advance
The query that I wrote
--Tagging each row whether it is repated more than twice or not
select * into #Repeat from (
SELECT CID, Count(*) as number,
case when Count(*)>1 then '1'
else '0'
end as repeat
FROM #Target GROUP BY CID
) temp
--Joining the above table to the master table and creating a new table
SELECT * into #T from(
select a.*,b.repeat from #Target a
left join #Repeat b ON a.CID = b.CID
) temp
alter table #T
add t_c Varchar(400)
UPDATE #T
SET t_c = CASE
WHEN repeat = '1' THEN 'control'
ELSE repeat
END
--creating a sub table which has no repetitive customer
SELECT * into #T1
from #T where t_c <> 'control'
--creating a sub table which has repetitive customer
select * from #T
SELECT * into #T2
from #T where t_c = 'control'
--splitting the table(#T1) into test and control
select * into #T3 from
(select *,
(case
when row_number() over (partition by RetailerCode,SEGMENT order by newid()) <= ((1-0.9-((select count(*) from #Target)/(select count(*) from #T2))) * count(*) over (partition by RetailerCode,SEGMENT)) then 'control'
else 'test'
end) as t_c_new
from #T1
where RETAILERCODE IN (SELECT DISTINCT RETAILERCODE FROM #Target
WHERE CID IN(
SELECT CID FROM
(SELECT CID, COUNT(*) AS NoOfOccurrences
FROM #Target GROUP BY CID
HAVING COUNT(*) = 1 ) temp
))
)temp1
--renaming a column
EXEC tempdb.sys.sp_rename N'#T2.t_c', N't_c_new', N'COLUMN';
ALTER TABLE #T3 DROP COLUMN t_c
--Merging the output
select * into #T4 from
(SELECT * from #T3 --1085612
union all
select * from #T2 -- 89622
) temp
--QA check…this is where I found out my logic is wrong
select RetailerCode, t_c_new, Segment
from
#T4 group by RetailerCode, t_c_new, Segment
order by RetailerCode, t_c_new, Segment
add a comment |
Business Context:
To put it simply, I would like to split my data set in to test and control and run some campaigns in the future. But there seems to be lot of complexities involved when I try to split it.
Data:
RetailerCode CID Segment
A6005 13SVC15 High
A6005 19VDE1F Low
A6005 1B3BD1F Medium
A6005 1B3HB48 Medium
A6005 1B3HB49 Low
A9006 1B3HB40 High
A9006 1B3HB41 High
A9006 1B3HB43 Low
A9006 1B3HB46 Medium
I have a master table like this which has the list of customers and their retailers, segment etc. (it has more than 30 columns, but I don’t want to show everything here). I would like to split this data set by adding a column, lets say “test_control” which will tell us whether particular row is test or control category. I can split this randomly but I need to follow the following rules,
- If a customer is tied to two or more retailers, then he should be in control group
- Each retailer will be provided with list of customers to target for the campaigns and the retailer will run the campaign. Here,
o Test-Control split should be done at Retailer level and then at segment level. For example, For each retailer
10% of their High customers to control and remaining 90% of their high customers to test.
10% of their Medium customers to control and remaining 90% of their Medium customers to test
10% of their Low customers to control and remaining 90% of their Low customers to test.
I can share the query that I wrote but that will totally confuse you guys 😊
But this is the high level approach that I followed
- Took out the records from the main table where customer occurred more than once and added a “test_control” column with “control” in it and saved it in a separate temp table 1
- Took out the records from the main table where customer occurred only once and saved it in a temp table 2
- On table 2, I tried to split to 10% (control) and 90% (test)
- Used union all to merge table 1 and table 2. But the ouput is totally wrong
Expected output

As you can see it split 10% and 90% at segment level as well
Please someone help me with this. Been working on this for past couple of days but no luck
Thanks in advance
The query that I wrote
--Tagging each row whether it is repated more than twice or not
select * into #Repeat from (
SELECT CID, Count(*) as number,
case when Count(*)>1 then '1'
else '0'
end as repeat
FROM #Target GROUP BY CID
) temp
--Joining the above table to the master table and creating a new table
SELECT * into #T from(
select a.*,b.repeat from #Target a
left join #Repeat b ON a.CID = b.CID
) temp
alter table #T
add t_c Varchar(400)
UPDATE #T
SET t_c = CASE
WHEN repeat = '1' THEN 'control'
ELSE repeat
END
--creating a sub table which has no repetitive customer
SELECT * into #T1
from #T where t_c <> 'control'
--creating a sub table which has repetitive customer
select * from #T
SELECT * into #T2
from #T where t_c = 'control'
--splitting the table(#T1) into test and control
select * into #T3 from
(select *,
(case
when row_number() over (partition by RetailerCode,SEGMENT order by newid()) <= ((1-0.9-((select count(*) from #Target)/(select count(*) from #T2))) * count(*) over (partition by RetailerCode,SEGMENT)) then 'control'
else 'test'
end) as t_c_new
from #T1
where RETAILERCODE IN (SELECT DISTINCT RETAILERCODE FROM #Target
WHERE CID IN(
SELECT CID FROM
(SELECT CID, COUNT(*) AS NoOfOccurrences
FROM #Target GROUP BY CID
HAVING COUNT(*) = 1 ) temp
))
)temp1
--renaming a column
EXEC tempdb.sys.sp_rename N'#T2.t_c', N't_c_new', N'COLUMN';
ALTER TABLE #T3 DROP COLUMN t_c
--Merging the output
select * into #T4 from
(SELECT * from #T3 --1085612
union all
select * from #T2 -- 89622
) temp
--QA check…this is where I found out my logic is wrong
select RetailerCode, t_c_new, Segment
from
#T4 group by RetailerCode, t_c_new, Segment
order by RetailerCode, t_c_new, Segment
1
I would recommend posting your code you have tried and actual output. It is far easier to look at code and give advice on what needs to be changed than start from scratch and try and provide a solution. Especially when it looks like you are relatively close to a solution. Also please tag the DBMS that you are using (oracle, sqlserver ect) as they can have slightly different syntax.
– Shaun Peterson
Jan 3 at 21:22
1
Yes, that's complicated. And the idea to do this step by step is good. But first we should sharpen the requirements. You want 90% of the high customers for a retailer in test and 10% in control, but all customers related to more then one customer must be in the control group. That means with 200 customers, and 10 of these related to another retailer, too, you need 10 more customers for the control group and the remaining 180 for the test group. But what if not 10 but 30 customers have another retailer, too? Then you already have 15% in the control group. How to go about this?
– Thorsten Kettner
Jan 3 at 21:28
have added my version of the code but its too long with all the temporary table
– dnarb
Jan 3 at 22:07
And what about my question? What if 70% of a retailer's customers are multi-retailer customers? Then you have 70% in control group instead of 10%. This contradicts your requirement, so what do you want the result to be then?
– Thorsten Kettner
Jan 3 at 22:22
@ThorstenKettner Sure that will totally screw the logic. But I did check the dataset, total no of rows = 1175234 and the repeating customers are just 88K. So yea its like around 7% only
– dnarb
Jan 3 at 22:34
add a comment |
Business Context:
To put it simply, I would like to split my data set in to test and control and run some campaigns in the future. But there seems to be lot of complexities involved when I try to split it.
Data:
RetailerCode CID Segment
A6005 13SVC15 High
A6005 19VDE1F Low
A6005 1B3BD1F Medium
A6005 1B3HB48 Medium
A6005 1B3HB49 Low
A9006 1B3HB40 High
A9006 1B3HB41 High
A9006 1B3HB43 Low
A9006 1B3HB46 Medium
I have a master table like this which has the list of customers and their retailers, segment etc. (it has more than 30 columns, but I don’t want to show everything here). I would like to split this data set by adding a column, lets say “test_control” which will tell us whether particular row is test or control category. I can split this randomly but I need to follow the following rules,
- If a customer is tied to two or more retailers, then he should be in control group
- Each retailer will be provided with list of customers to target for the campaigns and the retailer will run the campaign. Here,
o Test-Control split should be done at Retailer level and then at segment level. For example, For each retailer
10% of their High customers to control and remaining 90% of their high customers to test.
10% of their Medium customers to control and remaining 90% of their Medium customers to test
10% of their Low customers to control and remaining 90% of their Low customers to test.
I can share the query that I wrote but that will totally confuse you guys 😊
But this is the high level approach that I followed
- Took out the records from the main table where customer occurred more than once and added a “test_control” column with “control” in it and saved it in a separate temp table 1
- Took out the records from the main table where customer occurred only once and saved it in a temp table 2
- On table 2, I tried to split to 10% (control) and 90% (test)
- Used union all to merge table 1 and table 2. But the ouput is totally wrong
Expected output

As you can see it split 10% and 90% at segment level as well
Please someone help me with this. Been working on this for past couple of days but no luck
Thanks in advance
The query that I wrote
--Tagging each row whether it is repated more than twice or not
select * into #Repeat from (
SELECT CID, Count(*) as number,
case when Count(*)>1 then '1'
else '0'
end as repeat
FROM #Target GROUP BY CID
) temp
--Joining the above table to the master table and creating a new table
SELECT * into #T from(
select a.*,b.repeat from #Target a
left join #Repeat b ON a.CID = b.CID
) temp
alter table #T
add t_c Varchar(400)
UPDATE #T
SET t_c = CASE
WHEN repeat = '1' THEN 'control'
ELSE repeat
END
--creating a sub table which has no repetitive customer
SELECT * into #T1
from #T where t_c <> 'control'
--creating a sub table which has repetitive customer
select * from #T
SELECT * into #T2
from #T where t_c = 'control'
--splitting the table(#T1) into test and control
select * into #T3 from
(select *,
(case
when row_number() over (partition by RetailerCode,SEGMENT order by newid()) <= ((1-0.9-((select count(*) from #Target)/(select count(*) from #T2))) * count(*) over (partition by RetailerCode,SEGMENT)) then 'control'
else 'test'
end) as t_c_new
from #T1
where RETAILERCODE IN (SELECT DISTINCT RETAILERCODE FROM #Target
WHERE CID IN(
SELECT CID FROM
(SELECT CID, COUNT(*) AS NoOfOccurrences
FROM #Target GROUP BY CID
HAVING COUNT(*) = 1 ) temp
))
)temp1
--renaming a column
EXEC tempdb.sys.sp_rename N'#T2.t_c', N't_c_new', N'COLUMN';
ALTER TABLE #T3 DROP COLUMN t_c
--Merging the output
select * into #T4 from
(SELECT * from #T3 --1085612
union all
select * from #T2 -- 89622
) temp
--QA check…this is where I found out my logic is wrong
select RetailerCode, t_c_new, Segment
from
#T4 group by RetailerCode, t_c_new, Segment
order by RetailerCode, t_c_new, Segment
Business Context:
To put it simply, I would like to split my data set in to test and control and run some campaigns in the future. But there seems to be lot of complexities involved when I try to split it.
Data:
RetailerCode CID Segment
A6005 13SVC15 High
A6005 19VDE1F Low
A6005 1B3BD1F Medium
A6005 1B3HB48 Medium
A6005 1B3HB49 Low
A9006 1B3HB40 High
A9006 1B3HB41 High
A9006 1B3HB43 Low
A9006 1B3HB46 Medium
I have a master table like this which has the list of customers and their retailers, segment etc. (it has more than 30 columns, but I don’t want to show everything here). I would like to split this data set by adding a column, lets say “test_control” which will tell us whether particular row is test or control category. I can split this randomly but I need to follow the following rules,
- If a customer is tied to two or more retailers, then he should be in control group
- Each retailer will be provided with list of customers to target for the campaigns and the retailer will run the campaign. Here,
o Test-Control split should be done at Retailer level and then at segment level. For example, For each retailer
10% of their High customers to control and remaining 90% of their high customers to test.
10% of their Medium customers to control and remaining 90% of their Medium customers to test
10% of their Low customers to control and remaining 90% of their Low customers to test.
I can share the query that I wrote but that will totally confuse you guys 😊
But this is the high level approach that I followed
- Took out the records from the main table where customer occurred more than once and added a “test_control” column with “control” in it and saved it in a separate temp table 1
- Took out the records from the main table where customer occurred only once and saved it in a temp table 2
- On table 2, I tried to split to 10% (control) and 90% (test)
- Used union all to merge table 1 and table 2. But the ouput is totally wrong
Expected output

As you can see it split 10% and 90% at segment level as well
Please someone help me with this. Been working on this for past couple of days but no luck
Thanks in advance
The query that I wrote
--Tagging each row whether it is repated more than twice or not
select * into #Repeat from (
SELECT CID, Count(*) as number,
case when Count(*)>1 then '1'
else '0'
end as repeat
FROM #Target GROUP BY CID
) temp
--Joining the above table to the master table and creating a new table
SELECT * into #T from(
select a.*,b.repeat from #Target a
left join #Repeat b ON a.CID = b.CID
) temp
alter table #T
add t_c Varchar(400)
UPDATE #T
SET t_c = CASE
WHEN repeat = '1' THEN 'control'
ELSE repeat
END
--creating a sub table which has no repetitive customer
SELECT * into #T1
from #T where t_c <> 'control'
--creating a sub table which has repetitive customer
select * from #T
SELECT * into #T2
from #T where t_c = 'control'
--splitting the table(#T1) into test and control
select * into #T3 from
(select *,
(case
when row_number() over (partition by RetailerCode,SEGMENT order by newid()) <= ((1-0.9-((select count(*) from #Target)/(select count(*) from #T2))) * count(*) over (partition by RetailerCode,SEGMENT)) then 'control'
else 'test'
end) as t_c_new
from #T1
where RETAILERCODE IN (SELECT DISTINCT RETAILERCODE FROM #Target
WHERE CID IN(
SELECT CID FROM
(SELECT CID, COUNT(*) AS NoOfOccurrences
FROM #Target GROUP BY CID
HAVING COUNT(*) = 1 ) temp
))
)temp1
--renaming a column
EXEC tempdb.sys.sp_rename N'#T2.t_c', N't_c_new', N'COLUMN';
ALTER TABLE #T3 DROP COLUMN t_c
--Merging the output
select * into #T4 from
(SELECT * from #T3 --1085612
union all
select * from #T2 -- 89622
) temp
--QA check…this is where I found out my logic is wrong
select RetailerCode, t_c_new, Segment
from
#T4 group by RetailerCode, t_c_new, Segment
order by RetailerCode, t_c_new, Segment
edited Jan 3 at 21:55
a_horse_with_no_name
307k46468567
307k46468567
asked Jan 3 at 20:20
dnarbdnarb
205
205
1
I would recommend posting your code you have tried and actual output. It is far easier to look at code and give advice on what needs to be changed than start from scratch and try and provide a solution. Especially when it looks like you are relatively close to a solution. Also please tag the DBMS that you are using (oracle, sqlserver ect) as they can have slightly different syntax.
– Shaun Peterson
Jan 3 at 21:22
1
Yes, that's complicated. And the idea to do this step by step is good. But first we should sharpen the requirements. You want 90% of the high customers for a retailer in test and 10% in control, but all customers related to more then one customer must be in the control group. That means with 200 customers, and 10 of these related to another retailer, too, you need 10 more customers for the control group and the remaining 180 for the test group. But what if not 10 but 30 customers have another retailer, too? Then you already have 15% in the control group. How to go about this?
– Thorsten Kettner
Jan 3 at 21:28
have added my version of the code but its too long with all the temporary table
– dnarb
Jan 3 at 22:07
And what about my question? What if 70% of a retailer's customers are multi-retailer customers? Then you have 70% in control group instead of 10%. This contradicts your requirement, so what do you want the result to be then?
– Thorsten Kettner
Jan 3 at 22:22
@ThorstenKettner Sure that will totally screw the logic. But I did check the dataset, total no of rows = 1175234 and the repeating customers are just 88K. So yea its like around 7% only
– dnarb
Jan 3 at 22:34
add a comment |
1
I would recommend posting your code you have tried and actual output. It is far easier to look at code and give advice on what needs to be changed than start from scratch and try and provide a solution. Especially when it looks like you are relatively close to a solution. Also please tag the DBMS that you are using (oracle, sqlserver ect) as they can have slightly different syntax.
– Shaun Peterson
Jan 3 at 21:22
1
Yes, that's complicated. And the idea to do this step by step is good. But first we should sharpen the requirements. You want 90% of the high customers for a retailer in test and 10% in control, but all customers related to more then one customer must be in the control group. That means with 200 customers, and 10 of these related to another retailer, too, you need 10 more customers for the control group and the remaining 180 for the test group. But what if not 10 but 30 customers have another retailer, too? Then you already have 15% in the control group. How to go about this?
– Thorsten Kettner
Jan 3 at 21:28
have added my version of the code but its too long with all the temporary table
– dnarb
Jan 3 at 22:07
And what about my question? What if 70% of a retailer's customers are multi-retailer customers? Then you have 70% in control group instead of 10%. This contradicts your requirement, so what do you want the result to be then?
– Thorsten Kettner
Jan 3 at 22:22
@ThorstenKettner Sure that will totally screw the logic. But I did check the dataset, total no of rows = 1175234 and the repeating customers are just 88K. So yea its like around 7% only
– dnarb
Jan 3 at 22:34
1
1
I would recommend posting your code you have tried and actual output. It is far easier to look at code and give advice on what needs to be changed than start from scratch and try and provide a solution. Especially when it looks like you are relatively close to a solution. Also please tag the DBMS that you are using (oracle, sqlserver ect) as they can have slightly different syntax.
– Shaun Peterson
Jan 3 at 21:22
I would recommend posting your code you have tried and actual output. It is far easier to look at code and give advice on what needs to be changed than start from scratch and try and provide a solution. Especially when it looks like you are relatively close to a solution. Also please tag the DBMS that you are using (oracle, sqlserver ect) as they can have slightly different syntax.
– Shaun Peterson
Jan 3 at 21:22
1
1
Yes, that's complicated. And the idea to do this step by step is good. But first we should sharpen the requirements. You want 90% of the high customers for a retailer in test and 10% in control, but all customers related to more then one customer must be in the control group. That means with 200 customers, and 10 of these related to another retailer, too, you need 10 more customers for the control group and the remaining 180 for the test group. But what if not 10 but 30 customers have another retailer, too? Then you already have 15% in the control group. How to go about this?
– Thorsten Kettner
Jan 3 at 21:28
Yes, that's complicated. And the idea to do this step by step is good. But first we should sharpen the requirements. You want 90% of the high customers for a retailer in test and 10% in control, but all customers related to more then one customer must be in the control group. That means with 200 customers, and 10 of these related to another retailer, too, you need 10 more customers for the control group and the remaining 180 for the test group. But what if not 10 but 30 customers have another retailer, too? Then you already have 15% in the control group. How to go about this?
– Thorsten Kettner
Jan 3 at 21:28
have added my version of the code but its too long with all the temporary table
– dnarb
Jan 3 at 22:07
have added my version of the code but its too long with all the temporary table
– dnarb
Jan 3 at 22:07
And what about my question? What if 70% of a retailer's customers are multi-retailer customers? Then you have 70% in control group instead of 10%. This contradicts your requirement, so what do you want the result to be then?
– Thorsten Kettner
Jan 3 at 22:22
And what about my question? What if 70% of a retailer's customers are multi-retailer customers? Then you have 70% in control group instead of 10%. This contradicts your requirement, so what do you want the result to be then?
– Thorsten Kettner
Jan 3 at 22:22
@ThorstenKettner Sure that will totally screw the logic. But I did check the dataset, total no of rows = 1175234 and the repeating customers are just 88K. So yea its like around 7% only
– dnarb
Jan 3 at 22:34
@ThorstenKettner Sure that will totally screw the logic. But I did check the dataset, total no of rows = 1175234 and the repeating customers are just 88K. So yea its like around 7% only
– dnarb
Jan 3 at 22:34
add a comment |
2 Answers
2
active
oldest
votes
If you want to assign customers to a specific group you should order them first:
SELECT RetailerCode, CID, Segment,
CASE WHEN Percent_Rank()
Over (PARTITION BY retailercode, segment -- for each retailer/segment
ORDER BY ControlGroup, newid() -- all customers with multiple retailers are sorted low, i.e. will be in control group (if it's less than 10%)
) <= 0.1
THEN 'control'
ELSE 'test'
END AS GROUP
FROM
(
SELECT t.*,
-- flag customers to be put in control group
CASE WHEN Min(RetailerCode) Over (PARTITION BY CID)
= Max(RetailerCode) Over (PARTITION BY CID)
THEN 1 -- only a single retailer
ELSE 0 -- multiple retailers
END AS ControlGroup
-- if the RetailerCode/CID combination is unique:
-- CASE WHEN Count(*) Over (PARTITION BY CID) = 1
-- THEN 1 -- only a single retailer
-- ELSE 0 -- multiple retailers
-- END AS ControlGroup
FROM tab t
) AS dt;
Qucik question. Can you please explain this alone. How can are finding min(RetailerCode) here? How is it possible? Its RetailerCode is a character file type. So I was just wondering how that is possible? Can you share some insights? It will help me to work better in the future. Thanks
– dnarb
Jan 8 at 14:51
@dnarb: MIN/MAX work for (almost) every data type.Here it's similar toselect TOP 1 RetailerCode from tab ORDER BY RetailerCode(same for INT/DATE/TIMESTAMP/etc.)
– dnoeth
Jan 8 at 15:31
Got it thanks...
– dnarb
Jan 8 at 16:31
add a comment |
I am assuming that the customers who are with multiple retailers are not counted toward the 10% in the control group. You can find them using window functions.
The following then divides the remaining customers into the appropriately sized groups per retailer and segment:
select RetailerCode, CID, Segment,
(case when auto_in_control = 1 then 'control'
when row_number() over (partition by retailercode, segment, auto_in_control order by newid()) <=
0.1 * count(*) over (partition by retailercode, segment, auto_in_control)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If you want 10% of the customers in control for each retailer, with priority to those who are in multiple retailers, then:
select RetailerCode, CID, Segment,
(case when row_number() over (partition by retailercode, segmentorder by auto_in_control desc, newid()) <=
0.1 * count(*) over (partition by retailercode, segment)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If more than 10% of the customers for a given retailer in a given segment have multiple retailers, then only enough will be chosen for 10%. The remaining such customers will be in the test group.
By the way, this is poor test design. It would be better to assign customers to test/control independently of their retailer. More importantly, the control group and test groups are not representative, so I would not want to be trying to interpret results from such a test. Well, you (once upon a time) could have paid me enough ;)
Thanks @gordon Linoff: I tried your code, But the final split is not 10-90. :(
– dnarb
Jan 3 at 22:04
@dnarb . . . Not it is not, because customers who are in multiple retailers are automatically in the control. The rest are split 90/10.
– Gordon Linoff
Jan 3 at 22:22
Some customers in control by default plus 10% of the remaining customers results in more than 10% of all customers :-)
– dnoeth
Jan 3 at 22:25
Should it still be 0.1 in "0.1 * count(*)...." ? Since we have already classified repeating customers as control, applying 10% overall further increases control numbers. I think we need to change that I guess. Any thought?
– dnarb
Jan 3 at 22:25
1
@dnarb . . . Actually, that is pretty close to the 10% threshold for any given retailer, so this seems like a concern.
– Gordon Linoff
Jan 3 at 22:37
|
show 6 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54029238%2ftest-90-and-control-10-split-at-retailer-level-and-also-segment-level-in-s%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you want to assign customers to a specific group you should order them first:
SELECT RetailerCode, CID, Segment,
CASE WHEN Percent_Rank()
Over (PARTITION BY retailercode, segment -- for each retailer/segment
ORDER BY ControlGroup, newid() -- all customers with multiple retailers are sorted low, i.e. will be in control group (if it's less than 10%)
) <= 0.1
THEN 'control'
ELSE 'test'
END AS GROUP
FROM
(
SELECT t.*,
-- flag customers to be put in control group
CASE WHEN Min(RetailerCode) Over (PARTITION BY CID)
= Max(RetailerCode) Over (PARTITION BY CID)
THEN 1 -- only a single retailer
ELSE 0 -- multiple retailers
END AS ControlGroup
-- if the RetailerCode/CID combination is unique:
-- CASE WHEN Count(*) Over (PARTITION BY CID) = 1
-- THEN 1 -- only a single retailer
-- ELSE 0 -- multiple retailers
-- END AS ControlGroup
FROM tab t
) AS dt;
Qucik question. Can you please explain this alone. How can are finding min(RetailerCode) here? How is it possible? Its RetailerCode is a character file type. So I was just wondering how that is possible? Can you share some insights? It will help me to work better in the future. Thanks
– dnarb
Jan 8 at 14:51
@dnarb: MIN/MAX work for (almost) every data type.Here it's similar toselect TOP 1 RetailerCode from tab ORDER BY RetailerCode(same for INT/DATE/TIMESTAMP/etc.)
– dnoeth
Jan 8 at 15:31
Got it thanks...
– dnarb
Jan 8 at 16:31
add a comment |
If you want to assign customers to a specific group you should order them first:
SELECT RetailerCode, CID, Segment,
CASE WHEN Percent_Rank()
Over (PARTITION BY retailercode, segment -- for each retailer/segment
ORDER BY ControlGroup, newid() -- all customers with multiple retailers are sorted low, i.e. will be in control group (if it's less than 10%)
) <= 0.1
THEN 'control'
ELSE 'test'
END AS GROUP
FROM
(
SELECT t.*,
-- flag customers to be put in control group
CASE WHEN Min(RetailerCode) Over (PARTITION BY CID)
= Max(RetailerCode) Over (PARTITION BY CID)
THEN 1 -- only a single retailer
ELSE 0 -- multiple retailers
END AS ControlGroup
-- if the RetailerCode/CID combination is unique:
-- CASE WHEN Count(*) Over (PARTITION BY CID) = 1
-- THEN 1 -- only a single retailer
-- ELSE 0 -- multiple retailers
-- END AS ControlGroup
FROM tab t
) AS dt;
Qucik question. Can you please explain this alone. How can are finding min(RetailerCode) here? How is it possible? Its RetailerCode is a character file type. So I was just wondering how that is possible? Can you share some insights? It will help me to work better in the future. Thanks
– dnarb
Jan 8 at 14:51
@dnarb: MIN/MAX work for (almost) every data type.Here it's similar toselect TOP 1 RetailerCode from tab ORDER BY RetailerCode(same for INT/DATE/TIMESTAMP/etc.)
– dnoeth
Jan 8 at 15:31
Got it thanks...
– dnarb
Jan 8 at 16:31
add a comment |
If you want to assign customers to a specific group you should order them first:
SELECT RetailerCode, CID, Segment,
CASE WHEN Percent_Rank()
Over (PARTITION BY retailercode, segment -- for each retailer/segment
ORDER BY ControlGroup, newid() -- all customers with multiple retailers are sorted low, i.e. will be in control group (if it's less than 10%)
) <= 0.1
THEN 'control'
ELSE 'test'
END AS GROUP
FROM
(
SELECT t.*,
-- flag customers to be put in control group
CASE WHEN Min(RetailerCode) Over (PARTITION BY CID)
= Max(RetailerCode) Over (PARTITION BY CID)
THEN 1 -- only a single retailer
ELSE 0 -- multiple retailers
END AS ControlGroup
-- if the RetailerCode/CID combination is unique:
-- CASE WHEN Count(*) Over (PARTITION BY CID) = 1
-- THEN 1 -- only a single retailer
-- ELSE 0 -- multiple retailers
-- END AS ControlGroup
FROM tab t
) AS dt;
If you want to assign customers to a specific group you should order them first:
SELECT RetailerCode, CID, Segment,
CASE WHEN Percent_Rank()
Over (PARTITION BY retailercode, segment -- for each retailer/segment
ORDER BY ControlGroup, newid() -- all customers with multiple retailers are sorted low, i.e. will be in control group (if it's less than 10%)
) <= 0.1
THEN 'control'
ELSE 'test'
END AS GROUP
FROM
(
SELECT t.*,
-- flag customers to be put in control group
CASE WHEN Min(RetailerCode) Over (PARTITION BY CID)
= Max(RetailerCode) Over (PARTITION BY CID)
THEN 1 -- only a single retailer
ELSE 0 -- multiple retailers
END AS ControlGroup
-- if the RetailerCode/CID combination is unique:
-- CASE WHEN Count(*) Over (PARTITION BY CID) = 1
-- THEN 1 -- only a single retailer
-- ELSE 0 -- multiple retailers
-- END AS ControlGroup
FROM tab t
) AS dt;
answered Jan 3 at 22:23
dnoethdnoeth
46.1k31839
46.1k31839
Qucik question. Can you please explain this alone. How can are finding min(RetailerCode) here? How is it possible? Its RetailerCode is a character file type. So I was just wondering how that is possible? Can you share some insights? It will help me to work better in the future. Thanks
– dnarb
Jan 8 at 14:51
@dnarb: MIN/MAX work for (almost) every data type.Here it's similar toselect TOP 1 RetailerCode from tab ORDER BY RetailerCode(same for INT/DATE/TIMESTAMP/etc.)
– dnoeth
Jan 8 at 15:31
Got it thanks...
– dnarb
Jan 8 at 16:31
add a comment |
Qucik question. Can you please explain this alone. How can are finding min(RetailerCode) here? How is it possible? Its RetailerCode is a character file type. So I was just wondering how that is possible? Can you share some insights? It will help me to work better in the future. Thanks
– dnarb
Jan 8 at 14:51
@dnarb: MIN/MAX work for (almost) every data type.Here it's similar toselect TOP 1 RetailerCode from tab ORDER BY RetailerCode(same for INT/DATE/TIMESTAMP/etc.)
– dnoeth
Jan 8 at 15:31
Got it thanks...
– dnarb
Jan 8 at 16:31
Qucik question. Can you please explain this alone. How can are finding min(RetailerCode) here? How is it possible? Its RetailerCode is a character file type. So I was just wondering how that is possible? Can you share some insights? It will help me to work better in the future. Thanks
– dnarb
Jan 8 at 14:51
Qucik question. Can you please explain this alone. How can are finding min(RetailerCode) here? How is it possible? Its RetailerCode is a character file type. So I was just wondering how that is possible? Can you share some insights? It will help me to work better in the future. Thanks
– dnarb
Jan 8 at 14:51
@dnarb: MIN/MAX work for (almost) every data type.Here it's similar to
select TOP 1 RetailerCode from tab ORDER BY RetailerCode (same for INT/DATE/TIMESTAMP/etc.)– dnoeth
Jan 8 at 15:31
@dnarb: MIN/MAX work for (almost) every data type.Here it's similar to
select TOP 1 RetailerCode from tab ORDER BY RetailerCode (same for INT/DATE/TIMESTAMP/etc.)– dnoeth
Jan 8 at 15:31
Got it thanks...
– dnarb
Jan 8 at 16:31
Got it thanks...
– dnarb
Jan 8 at 16:31
add a comment |
I am assuming that the customers who are with multiple retailers are not counted toward the 10% in the control group. You can find them using window functions.
The following then divides the remaining customers into the appropriately sized groups per retailer and segment:
select RetailerCode, CID, Segment,
(case when auto_in_control = 1 then 'control'
when row_number() over (partition by retailercode, segment, auto_in_control order by newid()) <=
0.1 * count(*) over (partition by retailercode, segment, auto_in_control)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If you want 10% of the customers in control for each retailer, with priority to those who are in multiple retailers, then:
select RetailerCode, CID, Segment,
(case when row_number() over (partition by retailercode, segmentorder by auto_in_control desc, newid()) <=
0.1 * count(*) over (partition by retailercode, segment)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If more than 10% of the customers for a given retailer in a given segment have multiple retailers, then only enough will be chosen for 10%. The remaining such customers will be in the test group.
By the way, this is poor test design. It would be better to assign customers to test/control independently of their retailer. More importantly, the control group and test groups are not representative, so I would not want to be trying to interpret results from such a test. Well, you (once upon a time) could have paid me enough ;)
Thanks @gordon Linoff: I tried your code, But the final split is not 10-90. :(
– dnarb
Jan 3 at 22:04
@dnarb . . . Not it is not, because customers who are in multiple retailers are automatically in the control. The rest are split 90/10.
– Gordon Linoff
Jan 3 at 22:22
Some customers in control by default plus 10% of the remaining customers results in more than 10% of all customers :-)
– dnoeth
Jan 3 at 22:25
Should it still be 0.1 in "0.1 * count(*)...." ? Since we have already classified repeating customers as control, applying 10% overall further increases control numbers. I think we need to change that I guess. Any thought?
– dnarb
Jan 3 at 22:25
1
@dnarb . . . Actually, that is pretty close to the 10% threshold for any given retailer, so this seems like a concern.
– Gordon Linoff
Jan 3 at 22:37
|
show 6 more comments
I am assuming that the customers who are with multiple retailers are not counted toward the 10% in the control group. You can find them using window functions.
The following then divides the remaining customers into the appropriately sized groups per retailer and segment:
select RetailerCode, CID, Segment,
(case when auto_in_control = 1 then 'control'
when row_number() over (partition by retailercode, segment, auto_in_control order by newid()) <=
0.1 * count(*) over (partition by retailercode, segment, auto_in_control)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If you want 10% of the customers in control for each retailer, with priority to those who are in multiple retailers, then:
select RetailerCode, CID, Segment,
(case when row_number() over (partition by retailercode, segmentorder by auto_in_control desc, newid()) <=
0.1 * count(*) over (partition by retailercode, segment)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If more than 10% of the customers for a given retailer in a given segment have multiple retailers, then only enough will be chosen for 10%. The remaining such customers will be in the test group.
By the way, this is poor test design. It would be better to assign customers to test/control independently of their retailer. More importantly, the control group and test groups are not representative, so I would not want to be trying to interpret results from such a test. Well, you (once upon a time) could have paid me enough ;)
Thanks @gordon Linoff: I tried your code, But the final split is not 10-90. :(
– dnarb
Jan 3 at 22:04
@dnarb . . . Not it is not, because customers who are in multiple retailers are automatically in the control. The rest are split 90/10.
– Gordon Linoff
Jan 3 at 22:22
Some customers in control by default plus 10% of the remaining customers results in more than 10% of all customers :-)
– dnoeth
Jan 3 at 22:25
Should it still be 0.1 in "0.1 * count(*)...." ? Since we have already classified repeating customers as control, applying 10% overall further increases control numbers. I think we need to change that I guess. Any thought?
– dnarb
Jan 3 at 22:25
1
@dnarb . . . Actually, that is pretty close to the 10% threshold for any given retailer, so this seems like a concern.
– Gordon Linoff
Jan 3 at 22:37
|
show 6 more comments
I am assuming that the customers who are with multiple retailers are not counted toward the 10% in the control group. You can find them using window functions.
The following then divides the remaining customers into the appropriately sized groups per retailer and segment:
select RetailerCode, CID, Segment,
(case when auto_in_control = 1 then 'control'
when row_number() over (partition by retailercode, segment, auto_in_control order by newid()) <=
0.1 * count(*) over (partition by retailercode, segment, auto_in_control)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If you want 10% of the customers in control for each retailer, with priority to those who are in multiple retailers, then:
select RetailerCode, CID, Segment,
(case when row_number() over (partition by retailercode, segmentorder by auto_in_control desc, newid()) <=
0.1 * count(*) over (partition by retailercode, segment)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If more than 10% of the customers for a given retailer in a given segment have multiple retailers, then only enough will be chosen for 10%. The remaining such customers will be in the test group.
By the way, this is poor test design. It would be better to assign customers to test/control independently of their retailer. More importantly, the control group and test groups are not representative, so I would not want to be trying to interpret results from such a test. Well, you (once upon a time) could have paid me enough ;)
I am assuming that the customers who are with multiple retailers are not counted toward the 10% in the control group. You can find them using window functions.
The following then divides the remaining customers into the appropriately sized groups per retailer and segment:
select RetailerCode, CID, Segment,
(case when auto_in_control = 1 then 'control'
when row_number() over (partition by retailercode, segment, auto_in_control order by newid()) <=
0.1 * count(*) over (partition by retailercode, segment, auto_in_control)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If you want 10% of the customers in control for each retailer, with priority to those who are in multiple retailers, then:
select RetailerCode, CID, Segment,
(case when row_number() over (partition by retailercode, segmentorder by auto_in_control desc, newid()) <=
0.1 * count(*) over (partition by retailercode, segment)
then 'control'
else 'test'
end) as group
from (select t.*,
min(RetailerCode) over (partition by cid) as min_rc,
max(RetailerCode) over (partition by cid) as max_rc,
(case when min_rc = max_rc then 0 else 1 end) as auto_in_control
from Table t
) t
Order by RetailerCode;
If more than 10% of the customers for a given retailer in a given segment have multiple retailers, then only enough will be chosen for 10%. The remaining such customers will be in the test group.
By the way, this is poor test design. It would be better to assign customers to test/control independently of their retailer. More importantly, the control group and test groups are not representative, so I would not want to be trying to interpret results from such a test. Well, you (once upon a time) could have paid me enough ;)
edited Jan 3 at 22:39
answered Jan 3 at 21:35
Gordon LinoffGordon Linoff
794k37318421
794k37318421
Thanks @gordon Linoff: I tried your code, But the final split is not 10-90. :(
– dnarb
Jan 3 at 22:04
@dnarb . . . Not it is not, because customers who are in multiple retailers are automatically in the control. The rest are split 90/10.
– Gordon Linoff
Jan 3 at 22:22
Some customers in control by default plus 10% of the remaining customers results in more than 10% of all customers :-)
– dnoeth
Jan 3 at 22:25
Should it still be 0.1 in "0.1 * count(*)...." ? Since we have already classified repeating customers as control, applying 10% overall further increases control numbers. I think we need to change that I guess. Any thought?
– dnarb
Jan 3 at 22:25
1
@dnarb . . . Actually, that is pretty close to the 10% threshold for any given retailer, so this seems like a concern.
– Gordon Linoff
Jan 3 at 22:37
|
show 6 more comments
Thanks @gordon Linoff: I tried your code, But the final split is not 10-90. :(
– dnarb
Jan 3 at 22:04
@dnarb . . . Not it is not, because customers who are in multiple retailers are automatically in the control. The rest are split 90/10.
– Gordon Linoff
Jan 3 at 22:22
Some customers in control by default plus 10% of the remaining customers results in more than 10% of all customers :-)
– dnoeth
Jan 3 at 22:25
Should it still be 0.1 in "0.1 * count(*)...." ? Since we have already classified repeating customers as control, applying 10% overall further increases control numbers. I think we need to change that I guess. Any thought?
– dnarb
Jan 3 at 22:25
1
@dnarb . . . Actually, that is pretty close to the 10% threshold for any given retailer, so this seems like a concern.
– Gordon Linoff
Jan 3 at 22:37
Thanks @gordon Linoff: I tried your code, But the final split is not 10-90. :(
– dnarb
Jan 3 at 22:04
Thanks @gordon Linoff: I tried your code, But the final split is not 10-90. :(
– dnarb
Jan 3 at 22:04
@dnarb . . . Not it is not, because customers who are in multiple retailers are automatically in the control. The rest are split 90/10.
– Gordon Linoff
Jan 3 at 22:22
@dnarb . . . Not it is not, because customers who are in multiple retailers are automatically in the control. The rest are split 90/10.
– Gordon Linoff
Jan 3 at 22:22
Some customers in control by default plus 10% of the remaining customers results in more than 10% of all customers :-)
– dnoeth
Jan 3 at 22:25
Some customers in control by default plus 10% of the remaining customers results in more than 10% of all customers :-)
– dnoeth
Jan 3 at 22:25
Should it still be 0.1 in "0.1 * count(*)...." ? Since we have already classified repeating customers as control, applying 10% overall further increases control numbers. I think we need to change that I guess. Any thought?
– dnarb
Jan 3 at 22:25
Should it still be 0.1 in "0.1 * count(*)...." ? Since we have already classified repeating customers as control, applying 10% overall further increases control numbers. I think we need to change that I guess. Any thought?
– dnarb
Jan 3 at 22:25
1
1
@dnarb . . . Actually, that is pretty close to the 10% threshold for any given retailer, so this seems like a concern.
– Gordon Linoff
Jan 3 at 22:37
@dnarb . . . Actually, that is pretty close to the 10% threshold for any given retailer, so this seems like a concern.
– Gordon Linoff
Jan 3 at 22:37
|
show 6 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54029238%2ftest-90-and-control-10-split-at-retailer-level-and-also-segment-level-in-s%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I would recommend posting your code you have tried and actual output. It is far easier to look at code and give advice on what needs to be changed than start from scratch and try and provide a solution. Especially when it looks like you are relatively close to a solution. Also please tag the DBMS that you are using (oracle, sqlserver ect) as they can have slightly different syntax.
– Shaun Peterson
Jan 3 at 21:22
1
Yes, that's complicated. And the idea to do this step by step is good. But first we should sharpen the requirements. You want 90% of the high customers for a retailer in test and 10% in control, but all customers related to more then one customer must be in the control group. That means with 200 customers, and 10 of these related to another retailer, too, you need 10 more customers for the control group and the remaining 180 for the test group. But what if not 10 but 30 customers have another retailer, too? Then you already have 15% in the control group. How to go about this?
– Thorsten Kettner
Jan 3 at 21:28
have added my version of the code but its too long with all the temporary table
– dnarb
Jan 3 at 22:07
And what about my question? What if 70% of a retailer's customers are multi-retailer customers? Then you have 70% in control group instead of 10%. This contradicts your requirement, so what do you want the result to be then?
– Thorsten Kettner
Jan 3 at 22:22
@ThorstenKettner Sure that will totally screw the logic. But I did check the dataset, total no of rows = 1175234 and the repeating customers are just 88K. So yea its like around 7% only
– dnarb
Jan 3 at 22:34