Click here to Skip to main content
15,890,897 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have three tables Despatch, Activation and Replaced as below:
Despatch table:
ProductNo     VendorName   DispatchDate     LotQty
Product1         Vendor1           7/8/2013           20
Product2         Vendor2           7/8/2013           20
Product3         Vendor3           7/8/2013           20
Product4         Vendor4           7/8/2013           20
Product5         Vendor5           7/8/2013           20
Product6         Vendor6           7/8/2013           20

Activation table:
ProductNo     LotQty     ActivationDate
Product11       55           13/11/2013
Product12       55           13/11/2013
Product3         55           13/11/2013
Product4         55           13/11/2013
Product5         55           13/11/2013
Product6         55           13/11/2013

Replaced table
ProductNo     RecordDate
Product1         7/12/2013
Product7         7/12/2013
Product8         7/12/2013
Product9         7/12/2013
Product10         7/12/2013
Product11         7/12/2013

I want to compare data from all the three tables with Despatch table being base.

For example, if I enter LOTQty as 20 I should receive result based on following calculations:

1.> It should match all the ProductNo under Lot 20 from Despatch table with ProductNo in Activation table. If match found(in this case Product3,4,5 & 6) then next it should check dates.

2.> If Dispatch Date of matched ProductNo's are less than Activation Date only then it should consider.(Product3's Dispatch Date is less than Activation Date. So we count it as 1 and similarly for all others). Hence we find 4 matches.

3.> Product1 and Product2 did not found any match in Activation table. For such Product numbers we refer Replaced table. If match found (in this case Product1) it should compare Dispatch Date and Record Date. If Dispatch Date is lesser than Record Date only then we should consider the data(Product1's Dispatch date is less than RecordDate. So we count it as 1).

So now total quantity should be 5 i.e 4 by comparing Activation table and 1 by comparing with Replaced table.

The above are just sample table entries. My real tables contains many more columns which are trimmed to keep it simple. I tried preparing the query but I'm unable to find logic to cater my own requirement. Query I tried so far is as below:

SQL
select 
    d.LotQty, 
    ApprovedQty = count(d.ProductNo),
    d.DispatchDate,
    Installed = count(a.ProductNo) + count(r.ProductNo)
from 
    Despatch d 
left join 
    Activation a 
     on d.ProductNo = a.ProductNo 
    and d.DispatchDate < a.ActivationDate 
    and d.LotQty = a.LotQty
left join 
    Replaced r 
      on d.ProductNo = r.ProductNo 
     and d.DispatchDate < r.RecordDate
where 
    d.LotQty = 20
group by 
    d.LotQty, d.DispatchDate


This yields result as below:
LotQty       ApprovedQty       DispatchDate       Installed
20                 6                           2013-8-7             5

But when I try for my actual table it gives me unexpected result for two columns i.e "ApprovedQty" and "Installed". My approved Qty and Installed for Lot '1007' should be 984 and 869 respectively. but query returned me 990 and 1633, approx twice the expected Installed data.

While comparing Despatch table's ProductNo with Activation and Replaced, there may be possibility that there might be entries for same ProductNo in both Activation and Replaced tables. Hence the query should first check with Activation table. If it finds a match for ProductNo there, it shuould not search for same ProductNo in Replaced table. Only those ProductNo which found no match in Activation table or whose DispatchDate is greater than ActivationDate should be matched with Replaced table.

Help is deeply appreciated. Thanks in advance
Posted
Updated 6-Mar-15 2:24am
v4
Comments
coded007 5-Mar-15 2:12am    
try with this

select
d.LotQty,
ApprovedQty = count(d.ProductNo),
d.DispatchDate,
Installed = count(a.ProductNo) + count(r.ProductNo)
from
Despatch d
left join
Activation a
on d.ProductNo = a.ProductNo
and d.DispatchDate < a.ActivationDate
and d.LotQty = a.LotQty
left join
Replaced r
on d.ProductNo = a.ProductNo
and d.DispatchDate < r.RecordDate
where
d.LotQty = 20
group by
d.LotQty, d.DispatchDate
Sujeet KC 5-Mar-15 2:25am    
No it's giving me way more unexpected result. In both the left join you are matching d.ProductNo with a.ProductNo, where as I want to check first with Activation table i.e I want to match d.ProductNo with a.ProductNo. If the match is found then fine else it should match remaining d.ProductNo in r.ProductNo. and return the result combining both

1 solution

I've used recursive CTEs[^] (Common Table Expressions) in the following sql - see CodeProject Article How to use recursive CTE calls in T-SQL[^]

My thinking went as follows ... filter out what I need from the Activation table first (ignoring the LotQty for now) ...
SQL
With T1(ProductNo, DispatchDate, LotQty)
AS
(
    SELECT D.ProductNo, D.DispatchDate, D.LotQty
    from Despatch D
    INNER JOIN Activation A ON  D.ProductNo = A.ProductNo AND D.DispatchDate < A.ActivationDate
)

Then do the same with what I might want from the Replaced Table
SQL
With T2(ProductNo, DispatchDate, LotQty)
AS
(
    SELECT D.ProductNo, D.DispatchDate, D.LotQty
    FROM Despatch D
    INNER JOIN Replaced R ON D.ProductNo = R.ProductNo AND D.DispatchDate < R.RecordDate
)
I want to get everything from T1 and only the stuff from T2 that I don't already have and put it into T3. I added the [Source] column just to show where the data was really coming from
SQL
T3(Source, ProductNo, DispatchDate, LotQty)
AS
(
    SELECT 'T1', T1.* FROM T1
    UNION SELECT 'T2', * FROM T2 where T2.ProductNo NOT IN (SELECT T1.ProductNo from T1)
)
A quick query of the results shows that Products 3,4,5,6 are getting the data from T1, Product1 is getting it from T2 and Product2 has no other data.

Finally do the grouping/totals etc using Despatch as the base so the whole thing together becomes
SQL
With T1(ProductNo, DispatchDate, LotQty)
AS
(
    SELECT D.ProductNo, D.DispatchDate, D.LotQty
    from Despatch D
    INNER JOIN Activation A ON  D.ProductNo = A.ProductNo AND D.DispatchDate < A.ActivationDate
),
T2(ProductNo, DispatchDate, LotQty)
AS
(
    SELECT D.ProductNo, D.DispatchDate, D.LotQty
    FROM Despatch D
    INNER JOIN Replaced R ON D.ProductNo = R.ProductNo AND D.DispatchDate < R.RecordDate
),
T3(Source, ProductNo, DispatchDate, LotQty)
AS
(
    SELECT 'T1', T1.* FROM T1
    UNION SELECT 'T2', * FROM T2 where T2.ProductNo NOT IN (SELECT T1.ProductNo from T1)
)
SELECT 
   D.LotQty,
   ApprovedQty = count(D.ProductNo),
   D.DispatchDate,
   Installed = count(T3.ProductNo)
FROM Despatch D
LEFT OUTER JOIN T3 ON T3.ProductNo = D.ProductNo
WHERE D.LotQty = 20
GROUP BY D.LotQty, D.DispatchDate
 
Share this answer
 
Comments
Sujeet KC 5-Mar-15 9:53am    
Thanks a ton Chill60 for giving out hand here but it still shows unexpected results. Only two columns are differing. Approved quantity should get count only based on Despatch table i.e total count of ProductNo from Despatch fot lot 20. But for Installed it should perform all calculations. It has to check with Activation table first, if it finds a match then consider it. For those ProductNo's which didn't find a match with Activation table only those need to be checked with Replaced table.

Thanks in advance
CHill60 5-Mar-15 10:57am    
Got it ... I'll have another go
Sujeet KC 6-Mar-15 7:19am    
@Chill60 thanks for helping me. If you need further clarification with scenario, I have same question in StackOverflow. Please do refer this link :
http://stackoverflow.com/questions/28853364/matching-data-from-three-tables-in-sql-server-2008/28855348?noredirect=1#comment46042274_28855348
CHill60 6-Mar-15 7:46am    
I've gone back over this and with the sample data (and also some more sample data I produced myself) the query is giving the correct results - ApprovedQty is essentially just a count of all products on Despatch but Installed is only counting items from T1 where the date matches PLUS items from Replaced where the date matches and we haven't already considered it in T1. Are you sure it isn't your data that is at fault? The problem you are still reporting doesn't have any data in the sample
Sujeet KC 6-Mar-15 8:22am    
@ Chill60 Im sorry mate my bad. Actually the third table i.e Replaced shouldn't be having 2 columns, i.e VendorName and LotQty. I have eidted my question to reframe the Replaced table. So ideally it should match Despatch ProductNo with Activation ProductNo with particular Lot and those product No which didn't match there should be referred with Replaced data... Thanks for hinting me on fault

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900