Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 COMPLICATED MERGE PROBLEM

Author  Topic 

DavidSpackman
Starting Member

4 Posts

Posted - 2010-11-03 : 05:13:49
Hi,

I was wondering if anybody would be able to help suggest an answer for my problem?

I have a table (BOM) which contains the Bill of Materials for certain items.
For my purposes it is read-only

I have a query which saves a snapshot of the read-only table and saves the information into another table (CurrentSavedBOM) that I can edit, and use the information to load into other programs.

Every week (or every month) I would like to take another snapshot of the readonly table (Into a table called NewBOM) and output the specific changes that have made to the readonly BOM table.
I have been working on the guess that a MERGE statement is the best way to do this

Some issues I know of
  • Each parent part number can have a one to many relationship with child part numbers
  • The may be duplicate child part numbers for any one parent part number (This is for traceability, See ICN-1026-1212 example below). In these cases the child_start field for the original item will not change

Here is an example of CurrentSavedBOM

ps_parent, ps_desc ps_child, child_desc, ps_child_qty, child_start, child_end
------------------------------------------------------------------------------------------------
973-0-02-0240, FRONT PANEL, ICN-1026-1210, CABLE ASSY 4 WAY, 1, 16/10/2010, NULL
973-0-02-0240, FRONT PANEL, ICN-1026-1211, CABLE ASSY 6 WAY, 1, 16/10/2010, NULL
973-0-02-0240, FRONT PANEL, ICN-1026-1212, CABLE ASSY 3 WAY, 1, 16/10/2010, 17/10/2010
973-0-02-0240, FRONT PANEL, ICN-1026-1212, CABLE ASSY 3 WAY, 2, 18/10/2010, NULL
973-0-02-0240, FRONT PANEL, ICN-3077-0316, CRIMP CONTACT, 20, 12/02/2004, 15/10/2010
973-0-02-0241, FRONT PANEL V2,ICN-1026-1210, CABLE ASSY 4 WAY, 1, 16/10/2010, NULL

Here is an example of NewBOM

ps_parent, pt_desc ps_child, child_desc, ps_child_qty, child_start, child_end
------------------------------------------------------------------------------------------------
973-0-02-0240, FRONT PANEL, ICN-1026-1210, CABLE ASSY 4 WAY, 10, 16/10/2010, NULL
973-0-02-0240, FRONT PANEL, ICN-1026-1211, CABLE ASSY 6 WAY, 1, 16/10/2010, NULL
973-0-02-0240, FRONT PANEL, ICN-1026-1212, CABLE ASSY 3 WAY, 1, 16/10/2010, 17/10/2010
973-0-02-0240, FRONT PANEL, ICN-1026-1212, CABLE ASSY 3 WAY, 2, 18/10/2010, 20/10/2010
973-0-02-0240, FRONT PANEL, ICN-1026-1212, CABLE ASSY 3 WAY, 3, 21/10/2010, 30/10/2010
973-0-02-0240, FRONT PANEL, ICN-1026-1214, CABLE ASSY 10 WAY, 3, 20/10/2010, NULL
946-0-50-0200, COMPUTER, ICN-3098-1069, MOTHERBOARD, 1, 20/10/2010, NULL

So far I can think of a couple of different changes I need to check for between the NewBOM and CurrentSavedBOM
  • Brand new ps_parent number with a bunch of ps_child part numbers added in NewBOM
  • A ps_parent item and all it's child items are deleted from CurrentSavedBOM
  • ps_parent,ps_child and child_start match, but another field is different in NewBOM
  • A ps_child item has been added or deleted from an existing ps_parent item in NewBOM


Here is the code I have so far...
I had to split the query in into multiple merge statements because I need to match on different criteria.
I have not been able to figure out how to list the ps_parent items that have had new child items added (or deleted)

MERGE CurrentSavedBOM AS target
USING NewBOM AS source
ON target.ps_parent = source.ps_parent AND target.ps_child = source.ps_child AND target.child_start = source.child_start
WHEN MATCHED AND target.ps_desc<>source.ps_desc
OR target.child_desc<>source.child_desc
OR target.ps_child_qty<>source.ps_child_qty
OR target.child_end<>source.child_end
THEN
UPDATE SET
target.ps_desc = source.ps_desc,
target.child_desc = source.child_desc,
target.ps_child_qty = source.ps_child_qty,
target.child_end = source.child_end
OUTPUT $action,inserted.*,deleted.*;
GO

MERGE CurrentSavedBOM AS target
USING NewBOM AS source
ON target.ps_parent = source.ps_parent
WHEN NOT MATCHED BY TARGET THEN
INSERT (ps_parent, ps_desc, ps_child, child_desc, ps_child_qty, child_start, child_end)
VALUES (source.ps_parent, source.ps_desc, source.ps_child, source.child_desc, source.ps_child_qty, source.child_start, source.child_end)
OUTPUT $action,inserted.*;


Thank you very much for your help and suggestions, I've been stuck on this SO SO long now!

jcelko
Esteemed SQL Purist

547 Posts

Posted - 2010-11-03 : 11:55:24
Bad DDL leads to worse DML.

Have you seen the Nested sets model for BOM? It separates the tree structure from the nodes. So you keep the parts in one table and the BOMs in their own tables. It is trivial to compare the BOMs for structural changes, do counts of sub-assemblies, put lifetimes on the parts, etc.

Get a copy of TREES & HIERARCHIES IN SQL.

--CELKO--
Books in Celko Series for Morgan-Kaufmann Publishing
Analytics and OLAP in SQL
Data and Databases: Concepts in Practice
Data, Measurements and Standards in SQL
SQL for Smarties
SQL Programming Style
SQL Puzzles and Answers
Thinking in Sets
Trees and Hierarchies in SQL
Go to Top of Page

yosiasz
Master Smack Fu Yak Hacker

1635 Posts

Posted - 2010-11-03 : 12:23:50
David your approach is unsustainable, unmanageable. Step back and consider a fresh approach. You say
I have a query which saves a snapshot of the read-only table and saves the information into another table that I can edit, and use the information to load into other programs. What do you edit and upload to other programs?

If you don't have the passion to help people, you have no passion
Go to Top of Page

DavidSpackman
Starting Member

4 Posts

Posted - 2011-02-09 : 06:49:38
It has been a long time since I have looked at this post, due to other commitments.

I think I was over complicating my explanation.
Would it be possible for somebody to guide me to help a solution for a query to find the differences between 2 tables with the same structure.

Background:
I have 2 tables which are the same structure, these tables are snap shots of the same data taken at different times.
(The layout cannot change because I am reading the data from another source)


The table represents the bill of materials for items
It is setup as a adjacency model

Here is a simple example of the structure

Parent Child Qty
1 2 #(number value)
1 3 #
1 4 #
2 6 #
2 7 #
10 1 #

(Like Joe suggested, there is another table that is used to store the part information, this table just stores the structure of the BOM)


Is it possible to compare two tables to check for the differences?

My desired output is a list that shows me the following information
* Brand new parent items (and their children / qty information)
* Parent items that exist in both tables that have changed
** New child items
** Deleted child items
** Changes to qty
* Parent items that no longer exist

Thank you very much for your patience
Go to Top of Page
   

- Advertisement -