Comparing Parent-child combination from 2 different tables in SQL Server

那年仲夏 提交于 2020-02-06 07:57:12

问题


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:

  1. Find the mat_no, child pair in mat_rel where parent IS NULL
  2. 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):

  1. Find all rows from 2, where there's no matching row in mat_item. Use a LEFT JOIN or NOT EXISTS
  2. 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:

  1. Use both SQL's with UNION ALL


来源:https://stackoverflow.com/questions/59736175/comparing-parent-child-combination-from-2-different-tables-in-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!