I have to match each record in TABLE1 with at most 1 record in TABLE2.
There is a better way to match (CODE equality) and a poor one (in case of no CODE equality, let’s sort by CODE and match by index).
Let’s suppose as a first approximation that the code doing this might look like this :
SELECT
TABLE1.CODE AS CODE1,
TABLE2.CODE AS CODE2
FROM
(SELECT ROW_NUMBER() OVER(ORDER BY CODE) INDEX, CODE FROM TABLE1) T1
LEFT JOIN
(SELECT ROW_NUMBER() OVER(ORDER BY CODE) INDEX, CODE FROM TABLE2) T2
ON
(T1.CODE=T2.CODE) --CODE equality
OR
(T1.INDEX=T2.INDEX) --CODE equality
Let’s consider these tables :
TABLE1 TABLE2
+------+ +------+
| CODE | | CODE |
+------+ +------+
| AAA | | BBB |
| BBB | | CCC |
| CCC | | DDD |
+------+ +------+
The result will be :
CODE1 CODE2
----- -----
AAA BBB -> matched because of INDEX equality
BBB BBB -> matched because of CODE equality
BBB CCC -> matched because of INDEX equality
CCC CCC -> matched because of CODE equality
CCC DDD -> matched because of INDEX equality
Here comes the difficulty : I’d like to express the notion that despite there are 2 conditions of matching which are not mutually exclusive, the first one must be preferred to the second if possible, and the second must be evaluated if and only if the first one fails.
The wanted result being :
CODE1 CODE2
----- -----
AAA DDD -> matched because of INDEX equality between the cast-off records not able to match better
(corrected from the previous version where AAA was said to match expectedly with BBB)
BBB BBB -> matched thanks to CODE equality, no need to match on INDEX
CCC CCC -> matched thanks to CODE equality, no need to match on INDEX
And of course I would preferably obtain this behavior all-in-one-query to avoid a several-steps script, given that :
-
you can feel free to propose a totally different query : the one above was just there to illustrate the general idea, but it’s clear it doesn’t fit the needs. So, no need to try to preserve its structure.
-
I don’t really care about performance compared to the wish to perform an all-in-one-query matching. If subqueries are needed, let’s go ! 😉
Eager to read your suggestions ! 🙂
EDIT :
I made a strong error in my OP which is now corrected and deeply changes what can be considered as an accurate answer. The expected results were not right. My most humble apologies. 🙁
The idea is : match as much as you can on CODE equality, then consider only those which are left behind by this first matching algorithm to match them by INDEX. That’s why AAA which was incorrectly expected to INDEX-match with BBB (which already CODE-matches with another BBB), must in fact INDEX-match with another non CODE-matching item, in that case DDD.
Ok, I got it.
I post the answer in case it could be of any interest for somebody out there.
It can be adjusted depending on the final needs but the idea is there (I slightly changed the names of the fields/constants : it’s more close to the real life names and helped me to find the solution, it would have been too theorical otherwise).
Result :