I have three tables:
Table_1 - Main, where Global_ID is the primary key used in all tables.
| Global_ID |
| ------------ |
| 001 |
Table_2 - Using Global_ID to query for F_ID values
Global_ID | F_ID |
---|---|
001 | 1111 |
001 | 222222 |
001 | 33333 |
Table_3 - Using Global_ID to query for F_ID values
Global_ID | F_ID |
---|---|
001 | 444444 |
So, I need to do a query that returns The Global_ID and the values that are both equal and different in Table_2 and Table_3.
- If Table_2 and Table_3 have the same values, they need to be show in the same line.
- If Table_2 and Table_3 have different values, they need to be show in a new line Like this:
| Global ID | T2_F_ID | T3_F_ID |
| ------------ | ------------ | ------------ |
| 001 | 1111 | - |
| 001 | 222222 | - |
| 001 | 33333 | - |
| 001 | - | 444444 |
The way I am doing (case) is returning like this
Global ID | T2_F_ID | T3_F_ID |
---|---|---|
001 | 1111 | - |
001 | 222222 | - |
001 | 33333 | - |
This return is due to this query that I have poorly done
SELECT
DISTINCT T1.* "Global_ID",
ISNULL(CONVERT(VARCHAR,T2.F_ID),'-') "T2_F_ID",
CASE WHEN T2.F_ID IS NULL AND T3.F_ID IS NOT NULL THEN CONVERT(VARCHAR,T3.F_ID)
WHEN T2.F_ID IS NULL AND T3.F_ID IS NULL THEN '-'
WHEN T2.F_ID = T3.F_ID THEN T3.F_ID
WHEN T2.F_ID <> T3.F_ID THEN '-'
END "T3_F_ID"
FROM T1
LEFT JOIN T2 ON T2.Global_ID = T1.Global_ID
LEFT JOIN T3 ON T3.GLOBAL_ID = T1.Global_ID
This way I know there is some logic issues and that if Table_2 returns even 1 value, the values that are not the same in Table_3 will not be returned but I can't find out what to do and I am stuck...
Some other returns that might happen:
When there might be the same F_ID in Table_2 and Table_3, but also when the F_ID is not fouind in one of the tables.
| Global ID | T2_F_ID | T3_F_ID |
| ------------ | ------------ | ------------ |
| 001 | 1111 | 1111 |
| 001 | 222222 | - |
| 001 | 33333 | - |
| 001 | - | 444444 |When there are no F_ID in Table_2 and only in Table_3
| Global ID | T2_F_ID | T3_F_ID |
| ------------ | ------------ | ------------ |
| 001 | - | 444444 |When there are not the same F_ID in Table_3 and only in Table_2
| Global ID | T2_F_ID | T3_F_ID |
| ------------ | ------------ | ------------ |
| 001 | 1111 | - |
| 001 | 222222 | - |
| 001 | 33333 | - |When there are no values in Table_2 and Table_3
| Global ID | T2_F_ID | T3_F_ID |
| ------------ | ------------ | ------------ |
| 001 | - | - |When all values in Table_2 were found in Table_3
| Global ID | T2_F_ID | T3_F_ID |
| ------------ | ------------ | ------------ |
| 001 | 1111 | 1111 |
| 001 | 222222 | 222222 |
| 001 | 33333 | 33333 |
| 001 | 444444 | 444444 |
Another example with more Global_IDs:
Global ID | T2_F_ID | T3_F_ID |
---|---|---|
001 | 1111 | 1111 |
001 | 222222 | - |
001 | 33333 | 33333 |
001 | 444444 | 444444 |
002 | 1234 | - |
002 | 5678 | 5678 |
003 | 33333 | 33333 |
003 | 1212 | 1212 |
003 | - | 1111 |
004 | - | - |
005 | 33333 | 33333 |
005 | 444444 | 444444 |
005 | - | 1111 |
005 | - | 222222 |
005 | - | 33333 |
Please help.
2条答案
按热度按时间9rygscc11#
You can
union
2 queries together to obtain the results you want.Returns:
DBFiddle
Note: Providing the DDL+DML as shown here makes it much easier to assist.
bprjcwpo2#
Here is a solution that uses a
FULL OUTER JOIN
to join the two data tables (Table_2 and Table_3). That join (grouped using parentheses) is then joined back with the ID table (Table_1).Note the the parentheses after the
LEFT JOIN
causes the outer join between the Table_2 and Table_3 to be evaluated first. This is not a subselect.The problem with the above is that it doesn't properly handle duplicate values such as those that are present for Global_ID = 005. To handle duplicates, we need to assign distinct row values and add that to our logic. This can be done with some Common Table Expressions (CTEs) and a ROW_NUMBER() window function.
The
ORDER BY (SELECT NULL)
is just a don't care placeholder to satisfy the required syntax.Results:
| Global_Id | T2_F_ID | T3_F_ID |
| ------------ | ------------ | ------------ |
| 001 | 1111 | 1111 |
| 001 | 222222 | null |
| 001 | 33333 | 33333 |
| 001 | 444444 | 444444 |
| 002 | 1234 | null |
| 002 | 5678 | 5678 |
| 003 | null | 1111 |
| 003 | 1212 | 1212 |
| 003 | 33333 | 33333 |
| 004 | null | null |
| 005 | null | 1111 |
| 005 | null | 222222 |
| 005 | 33333 | 33333 |
| 005 | null | 33333 |
| 005 | 444444 | 444444 |
See this db<>fiddle .
It is worth noting that the table joins could also be rearranged and rewritten as:
The results are identical. Which is more readable and best conveys intent is subjective.