问题
I have table MAT_ITEM
and data as follows
+--------+-------+
| MAT_NO | CHILD |
+--------+-------+
| 9856 | 874 |
| 9856 | 856 |
| 9856 | 548 |
| 9883 | 596 |
| 9883 | 356 |
| 7845 | 101 |
| 7845 | 908 |
| 7845 | 206 |
+--------+-------+
Another table MAT_REL
and data as follows:
+--------+----------+----------+
| MAT_NO | PARENT | CHILD |
+--------+----------+----------+
| 9856 | | STEEL |
| 9856 | STEEL | 874 |
| 9856 | STEEL | 856 |
| 9856 | STEEL | 548 |
| 9856 | A-STEEL | 874 |
| 9856 | B_STEEL | 856 |
| 7845 | | METAL |
| 7845 | O_METAL | 102 |
| 7845 | I_METAL | 908 |
| 7845 | METAL | 102 |
| 7845 | METAL | 908 |
| 7845 | METAL | 206 |
| 7845 | METAL | 769 |
| 9883 | | CARBON |
| 9883 | B_CARBON | 596 |
| 9883 | C_CARBON | 356 |
| 9883 | CARBON | 596 |
| 9883 | CARBON | 147 |
+--------+----------+----------+
Basically the row with empty PARENT
in MAT_REL
is considered as the TOP Parent and it's child will be considered as PARENT
for my comparison in MAT_REL
. MAT_REL
may contain Parent as other values as well (eg., A_STEEL,B_CARBON etc.,) which I'm not worried about.
Something like this in MAT_REL
is what I'm considering for comparison.
+--------+--------+-------+
| MAT_NO | PARENT | CHILD |
+--------+--------+-------+
| 9856 | STEEL | 874 |
| 9856 | STEEL | 856 |
| 9856 | STEEL | 548 |
| 9883 | CARBON | 596 |
| 9883 | CARBON | 147 |
| 7845 | METAL | 102 |
| 7845 | METAL | 908 |
| 7845 | METAL | 206 |
| 7845 | METAL | 769 |
+--------+--------+-------+
Now I want to compare MAT_ITEM
and MAT_REL
whether the MAT_NO & CHILD
in MAT_ITEM
combo is same as MAT_NO
,PARENT
& CHILD
in MAT_REL
.I'm trying to get the non-matching rows. We cannot directly compare MAT_ITEM
and MAT_REL
.Direct comparison will not work because if you see for MAT_NO 9883 , direct comparison might give the result as rows are same but we have to check for CARBON and not others(B_CARBON) as overall
Expected output : (with or without child)
9883
7845
I am able to get the detail for single MAT_NO.
SELECT * FROM MAT_ITEM WHERE MAT_NO='7845'
SELECT * FROM MAT_REL
WHERE MAT_NO = '7845' AND PARENT IS NULL -- METAL (using this below)
SELECT * FROM MAT_REL
WHERE MAT_NO = '7845' AND PARENT = 'METAL'
SELECT DISTINCT CHILD FROM MAT_ITEM WHERE MAT_NO = '7845'
EXCEPT
SELECT DISTINCT CHILD FROM MAT_REL
WHERE MAT_NO = '7845' AND PARENT = 'METAL' -- will return some rows --101
but not sure how to do for whole set of combinations.
回答1:
Answer as per comments on the question. I tried it out on a SQLite database, and since the syntax may be off compared to SQLServer, I can only give you directions. I do not have a link to a database.
Finding the basics:
- Find the mat_no, child pair in mat_rel where parent IS NULL
- Find all rows in mat_rel that matches the mat_no and where parent matches the child from 1. Add the SQL from 1. in a JOIN like (SELECT ..).
Finding mismatch (comparing child=child and mat_no=mat_no):
- Find all rows from 2, where there's no matching row in mat_item. Use a LEFT JOIN or NOT EXISTS
- Find all rows in mat_item where there's no matching row in mat_rel from 2. Use a RIGHT JOIN or NOT EXISTS.
Finding both 3 and 4:
- Use both SQL's with UNION ALL
来源:https://stackoverflow.com/questions/59736175/comparing-parent-child-combination-from-2-different-tables-in-sql-server