'Is there a loop function which can automatize this?
I have these lines of code which you can find below and I want to automatize this (most probably using a loop function) by just giving the input: 'CITY', 'COUNTY', 'PARTNERS', 'PRODUCT'. Is there any way to do this? Also the names of temporary tables ('CUSTOMERS_MND_0', CUSTOMERS_MND_1', 'CUSTOMERS_MND_2', 'CUSTOMERS_MND_3', 'CUSTOMERS_MND_4') are not important, so those can be renamed as the variable names.
The issue I'm facing is that "UNIQUE_KEY" is not unique and I need to have it unique in the final db. Please find an example.
Initial DB:
| UNIQUE_KEY | CITY | COUNTY | PARTNERS | PRODUCT |
|---|---|---|---|---|
| 111 | VIENNA | A | W | 1 |
| 111 | NAPLES | B | X | 7 |
| 112 | VIENNA | B | Y | 3 |
| 113 | NAPLES | B | W | 4 |
| 113 | NAPLES | A | W | 4 |
| 114 | VIENNA | A | W | 1 |
| 115 | VIENNA | B | W | 4 |
| 115 | NAPLES | A | W | 4 |
| 115 | VIENNA | B | X | 7 |
| 115 | VIENNA | B | Y | 3 |
| 116 | NAPLES | B | W | 4 |
| 116 | NAPLES | A | W | 4 |
| 116 | VIENNA | A | W | 1 |
FINAL DB:
| UNIQUE_KEY | CITY | COUNTY | PARTNERS | PRODUCT |
|---|---|---|---|---|
| 111 | VIENNA | A | W | 1 |
| 112 | VIENNA | B | Y | 3 |
| 113 | NAPLES | B | W | 4 |
| 114 | VIENNA | A | W | 1 |
| 115 | VIENNA | B | Y | 3 |
| 116 | VIENNA | A | W | 1 |
SELECT AA.*
INTO #CUSTOMERS_MND_1
FROM #CUSTOMERS_MND_0 AA
INNER JOIN (SELECT UNIQUE_KEY,
MAX(CITY) AS MAXCITY
FROM #CUSTOMERS_MND_0
GROUP BY UNIQUE_KEY) BB ON AA.UNIQUE_KEY = BB.UNIQUE_KEY
AND AA.CITY = BB.MAXCITY;
DROP TABLE #CUSTOMERS_MND_0;
SELECT AA.*
INTO #CUSTOMERS_MND_2
FROM #CUSTOMERS_MND_1 AA
INNER JOIN (SELECT UNIQUE_KEY,
MAX(COUNTY) AS MAXCOUNTY
FROM #CUSTOMERS_MND_1
GROUP BY UNIQUE_KEY) BB ON AA.UNIQUE_KEY = BB.UNIQUE_KEY
AND AA.COUNTY = BB.MAXCOUNTY;
DROP TABLE #CUSTOMERS_MND_1;
SELECT AA.*
INTO #CUSTOMERS_MND_3
FROM #CUSTOMERS_MND_2 AA
INNER JOIN (SELECT UNIQUE_KEY,
MAX(PARTNERS) AS MAXPARTNERS
FROM #CUSTOMERS_MND_2
GROUP BY UNIQUE_KEY) BB ON AA.UNIQUE_KEY = BB.UNIQUE_KEY
AND (AA.PARTNERS = BB.MAXPARTNERS
OR AA.PARTNERS IS NULL
AND BB.MAXPARTNERS IS NULL);
DROP TABLE #CUSTOMERS_MND_2;
SELECT AA.*
INTO #CUSTOMERS_MND_4
FROM #CUSTOMERS_MND_3 AA
INNER JOIN (SELECT UNIQUE_KEY,
MAX(PRODUCT) AS MAXPRODUCT
FROM #CUSTOMERS_MND_3
GROUP BY UNIQUE_KEY) BB ON AA.UNIQUE_KEY = BB.UNIQUE_KEY
AND (AA.PRODUCT = BB.MAXPRODUCT
OR AA.PRODUCT IS NULL
AND BB.MAXPRODUCT IS NULL);
DROP TABLE #CUSTOMERS_MND_3;
It works, but for more joins it is not time efficient.
Solution 1:[1]
my guess is you want the max city per unique key, within that city the max county, within that county the max partners and within that partner the max product in which case generating a row number and selecting row number 1 gives the same result as your code
create table #CUSTOMERS_MND_0
(unique_key int,city varchar(10),county varchar(10),partners varchar(10),product int);
go
insert into #CUSTOMERS_MND_0 values
(111,'vienna','a','w',7),(111,'naples','b','x',7),(111,'vienna','b','w',6),(111,'vienna','b','x',5)
go
with cte as
(select *, row_number() over (partition by unique_key order by city desc , county desc, partners desc,product desc) rn
from
#CUSTOMERS_MND_0
)
select * from cte where rn = 1;
your code plus
select * from #CUSTOMERS_MND_3
unique_key city county partners product
----------- ---------- ---------- ---------- -----------
111 vienna b x 5
my code
unique_key city county partners product rn
----------- ---------- ---------- ---------- ----------- --------------------
111 vienna b x 5 1
Now we have simplified code we can think about automation. You say you want to supply known columns as part of this process but unique key will always be required and source tables is known so--see https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=355f06fb7d51ba8fed9ea4e6d1e23d07 for an example of how using a temp table to hold the columns and the priority order in this case by identity. Then read up on dynamic sql..
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
