Reputation: 1931
I have Cross Joined 3 tables and now i want to filter down the result using combined column values. What i mean is that if a row has values (a,b,c) for 3 columns, then it be treated as same as a row with these 3 values(b,c,a) or any other combination of a, b and c.
The query that generated the results is:
;WITH CTE
AS (SELECT T1.LastName AS T1LASTNAME,
T2.LastName AS T2LASTNAME,
T3.LastName AS T3LASTNAME,
( T1.TOTALSALES + T2.TOTALSALES + T3.TOTALSALES ) AS TOTALSALES,
( T1.SALARY + T2.SALARY + T3.SALARY ) AS TOTALSALARY
FROM #TOPSALESPERSON AS T1
CROSS JOIN #TOPSALESPERSON AS T2
CROSS JOIN #TOPSALESPERSON AS T3
WHERE T1.BusinessEntityID != T2.BusinessEntityID
AND T2.BusinessEntityID != T3.BusinessEntityID
AND T1.BusinessEntityID != T3.BusinessEntityID
AND T1.NAME != T2.NAME
AND T1.NAME != T3.NAME
AND T3.NAME != T2.NAME)
SELECT DISTINCT *
FROM CTE
WHERE CTE.TOTALSALARY < 210000
ORDER BY TOTALSALES DESC
So here, these 3 rows should be filtered down to one row:
T1LASTNAME T2LASTNAME T3LASTNAME TOTALSALES TOTALSALARY
------------------------------------------------------------
Campbell Mitchell Saraiva 2924710.74 195000.00
Campbell Saraiva Mitchell 2924710.74 195000.00
Mitchell Campbell Saraiva 2924710.74 195000.00
Here is a SQL fiddle link for the schema and data to play with: http://sqlfiddle.com/#!9/c456d8/1/0
Thanks
Upvotes: 1
Views: 1664
Reputation: 522396
Change the restriction on the names to the following logic:
T1.NAME <= T2.NAME AND
T1.NAME <= T3.NAME AND
T2.NAME <= T3.NAME
This solves your original problem because now the three names can only appear in ascending order.
;WITH CTE
AS (SELECT T1.LastName AS T1LASTNAME,
T2.LastName AS T2LASTNAME,
T3.LastName AS T3LASTNAME,
( T1.TOTALSALES + T2.TOTALSALES + T3.TOTALSALES ) AS TOTALSALES,
( T1.SALARY + T2.SALARY + T3.SALARY ) AS TOTALSALARY
FROM #TOPSALESPERSON AS T1
CROSS JOIN #TOPSALESPERSON AS T2
CROSS JOIN #TOPSALESPERSON AS T3
WHERE T1.BusinessEntityID != T2.BusinessEntityID
AND T2.BusinessEntityID != T3.BusinessEntityID
AND T1.BusinessEntityID != T3.BusinessEntityID
AND T1.NAME <= T2.NAME
AND T1.NAME <= T3.NAME
AND T2.NAME <= T3.NAME)
Note that we could still get duplicate records here if two or three names be the same. But your SELECT DISTINCT
would actually take care of that problem and remove those duplicates.
Upvotes: 4
Reputation: 1
To my knowledge this isn't a way to do this without writing a custom function. You can write a function which takes two strings as input. The first input string is the concatenation of the name columns you have mentioned in your example. The concatenation should delimit the string by the delimiter of your choice. The second input string should be your delimiter.
Here is how I concatenated the names:
concat(t1lastname, '--', t2lastname, '--', t3lastname)
Your custom function then takes the input string and tokenizes the string by delimiter and sorts it. Once the names have been sorted, they are concatenated back together and returned as output in sorted order.
function sort_delimited_string(concatenated_string, delimiter_string)
{
...
return concatenated_sorted_string;
}
your query would look somehting like this:
select distinct(sort_delmited_string(concat(t1lastname, '--', t2lastname, '--', t3lastname), '--')) from table1;
Upvotes: 0