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 2012 Forums
 Transact-SQL (2012)
 Revised post on Tricky Update

Author  Topic 

sqlpal2007
Posting Yak Master

200 Posts

Posted - 2015-04-07 : 11:36:36
Hello All,

I have to build conditional update in SQL script. Can someone please help me atlest to start of the query?

Here is the criteria:

1. If tbl1 has no record with Batch = NULL and tbl1 and tbl2 have perfect match for Identifier-Container, Batch-Lot and Material-FromValue, get all the matched records from tbl2. Update StatusID = 1
2. If tbl1 has only one record and with Batch = NULL record for Identifier, Batch and Material combination, get all tbl2 records for Identifier-Container and Material-FromValue. Update StatusID = 2
3. If tbl1 has more than one Batch = NULL records for Identifier, Batch and Material combination, update StatusID = 7 (error)
4. If tbl1 has atleast one Batch = NULL but rest of the records match with tbl2, update StatusID = 8 (error)
5. If tbl1 has two records with Batch = NULL, but Material is different then update StatusID = 3 (example 'Del006')
In example 'Del005', these two records are bad as per #4
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del005', 'B5-1', 'M5-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del005', NULL, 'M5-1')

But this record is good as per 2#
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del005', NULL, 'M5-2')

SQL -
create table #tbl1 (Identifier varchar(10), Batch varchar(10), Material varchar(10), StatusID INT)
create table #tbl2 (Container varchar(10), Lot varchar(10), FromValue varchar(10))

insert into #tbl1 (Identifier, Batch, Material) VALUES('Del001', 'B1-1', 'M1-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del001', 'B1-1', 'M1-2')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del002', NULL, 'M2-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del003', 'B3-1', 'M3-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del004', NULL, 'M4-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del004', NULL, 'M4-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del005', 'B5-1', 'M5-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del005', NULL, 'M5-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del005', NULL, 'M5-2')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del006', NULL, 'M6-1')
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del006', NULL, 'M6-2')

insert into #tbl2 VALUES ('Del001', 'B1-1', 'M1-1')
insert into #tbl2 VALUES ('Del001', 'B1-1', 'M1-2')
insert into #tbl2 VALUES ('Del002', 'B2-1', 'M2-1')
insert into #tbl2 VALUES ('Del002', 'B2-2', 'M2-1')
insert into #tbl2 VALUES ('Del003', 'B3-1', 'M3-1')
insert into #tbl2 VALUES ('Del003', 'B3-1', 'M3-1')
insert into #tbl2 VALUES ('Del005', 'B5-2', 'M5-2')
insert into #tbl2 VALUES ('Del006', 'B6-1', 'M6-2')

Thanks,

gbritton
Master Smack Fu Yak Hacker

2780 Posts

Posted - 2015-04-07 : 13:44:34
I think there's a problem in your rules. e.g. for 2:

quote:

2. If tbl1 has only one record and with Batch = NULL record for Identifier, Batch and Material combination, get all tbl2 records for Identifier-Container and Material-FromValue. Update StatusID = 2



this implies that tbl2.lot must also be null, otherwise there is no match on Batch-Lot (as per rule 1), yet you say that:

quote:

But this record is good as per 2#
insert into #tbl1 (Identifier, Batch, Material) VALUES('Del005', NULL, 'M5-2')



Yet in #tbl2 the only row that almost matches is:


insert into #tbl2 VALUES ('Del005', 'B5-2', 'M5-2')


but here, lot is NOT null, so it doesn't match.

Would you please clarify?

btw, the update for the Rule 1 is:


-- 1.
update tbl2
set statusid = 1
-- select *
from #tbl2 tbl2
join #tbl1 tbl1
on tbl1.identifier = tbl2.container
and tbl1.Material = tbl2.FromValue
where tbl1.batch is null and tbl2.lot is null


(note that I left the select * in there, commented out, for testing purposes.
Go to Top of Page

sqlpal2007
Posting Yak Master

200 Posts

Posted - 2015-04-07 : 14:10:10
Thank you for the reply gbritton.

Yes, you are correct. The Lot will never match with Batch as Batch is NULL. But if there is only one record in tbl1 with Batch = NULL where Identifier-Container and Material-FromValue match with tbl1 and tbl2 then the file is good. All the matching records from tbl2 (there could be more than one records in tbl2 where Identifier-Container and Material-FromValue match) should be returned.

Hope this answers the question.
Go to Top of Page

sqlpal2007
Posting Yak Master

200 Posts

Posted - 2015-04-07 : 14:47:35
The update for first senario doesn't return any data. Should the where clause be batch is NOT null and tbl2.lot is NOT null?

Thanks for your help



Go to Top of Page

gbritton
Master Smack Fu Yak Hacker

2780 Posts

Posted - 2015-04-07 : 14:49:10
Here's the second rule:


-- 2.
update tbl1
set statusid = statusid
--select *
from #tbl2 tbl2
join
(
select count(*) ct, Identifier, Batch, Material
from #tbl1 tbl1
group by Identifier, Batch, Material
) tbl1
on tbl1.Identifier = tbl2.Container
and tbl1.Material = tbl2.FromValue
where tbl1.ct = 1 and tbl1.batch is null
Go to Top of Page

gbritton
Master Smack Fu Yak Hacker

2780 Posts

Posted - 2015-04-07 : 14:52:29
quote:
Originally posted by sqlpal2007

The update for first senario doesn't return any data. Should the where clause be batch is NOT null and tbl2.lot is NOT null?

Thanks for your help



you're mostly right,though this may be better:


update tbl2
set statusid = 1
-- select *
from #tbl2 tbl2
join #tbl1 tbl1
on tbl1.identifier = tbl2.container
and tbl1.Material = tbl2.FromValue
and tbl1.batch = tbl2.lot


Still I have a question:
" If tbl1 has no record with Batch = NULL"
Do you mean for the entire table there is no row where Batch is NULL? Or do you mean within an Identifier, Material grouping? If the latter there's more work to do
Go to Top of Page

sqlpal2007
Posting Yak Master

200 Posts

Posted - 2015-04-07 : 14:54:00
second senario query works perfect :-)
Go to Top of Page

sqlpal2007
Posting Yak Master

200 Posts

Posted - 2015-04-07 : 15:04:50
For the Identifier and Material group if all the columns (including Batch is not NULL) contain values not the entire table. The tbl1 will have more than one records.
If all Identifier, Batch and Material have values and those exactly match with tbl2 (and tbl2 does not bring back more records for same three keys).
Go to Top of Page

gbritton
Master Smack Fu Yak Hacker

2780 Posts

Posted - 2015-04-07 : 15:50:04
So, #1 is harder:


with no_nulls as

-- CTE to return Identifier, Material pairs in #tbl1 where Batch is never null
(
select *
from
(
select count(*) ct, Identifier, Material
from #tbl1 tbl1
group by Identifier, Material
) t1
where not exists
(
select 1
from #tbl1
where Identifier = t1.Identifier
and Material = t1.Material
and batch is null
)
),

-- CTE to add the batch back in
no_nulls_batch as
(
select t1.* from #tbl1 t1
join no_nulls n
on t1.Identifier = n.Identifier
and t1.Material = n.Material
)

-- Actual UPDATE
update t2
set statusId = 2
from #tbl2 t2
join no_nulls_batch nn
on t2.Container = nn.Identifier
and t2.Lot = nn.Batch
and t2.FromValue = nn.Material


Actually, #2 may need to work similarly.
Go to Top of Page

sqlpal2007
Posting Yak Master

200 Posts

Posted - 2015-04-07 : 19:13:38
The first scenario with the new query works great!

Thank you for all your help. Do you have an idea on how to move forward with 3, 4 and 5#?

Thanks,
Go to Top of Page

gbritton
Master Smack Fu Yak Hacker

2780 Posts

Posted - 2015-04-08 : 17:15:28
3 is like 2 but for ct > 1

4 is like 1 but for ct >= 1

5 is a variation on 2, I think
Go to Top of Page

sqlpal2007
Posting Yak Master

200 Posts

Posted - 2015-04-09 : 09:33:06
Okay. Thank yougbritton. I will take the first two and modify for the rest. Again, thank you so much for your help.
Go to Top of Page
   

- Advertisement -