2

I have two tables both containing employee data, TableA and TableB, I'm joining them based on 2 id's (one it's userID and the other mID (month based id)) using a LEFT OUTER JOIN which returns NULL in about 20% of the results because TableB it's incomplete. I want -if possible- a query that detects if the join doesn't find a match and subtract one month to mID so the JOIN can cover at least a percentage of missing data with just old data.

I don't know if it's a way too complex query but I had in mind something like:

SELECT T1.*, T2.*
FROM TABLEA
LEFT OUTER JOIN TABLEB
ON T2.USERID = T1.USERID AND (CASE WHEN (T2.HID = T1.HID) = NULL THEN (T2.HID = T1.HID-1))

Appreciate any help.

4
  • 2
    a comment : use "IS NULL" not "= NULL" Commented Mar 19, 2019 at 18:59
  • 6
    I think you need to provide some sample data and desired output here. Commented Mar 19, 2019 at 19:07
  • 1
    There are a lot reasons why it is really bad idea to try to deal with keys in this manner. Why is JOINing using 'OLD' data even valid? Commented Mar 19, 2019 at 19:27
  • @DavidTansey, It's likely that TableB contains the same data (95%-ish usually) as one month earlier, but I'm not able to update the table myself, besides, that table just contains reference data about the same employees of tableA Commented Mar 19, 2019 at 19:34

2 Answers 2

1

I think this is what you are really wanting to do; the downside is there is a bit more logic and it would be duplicated per column, but it provides a fine grain of control.

DECLARE @TableA TABLE (USERID INT,HID INT,SomeData VARCHAR(20))
DECLARE @TableB TABLE (USERID INT,HID INT,SomeData VARCHAR(20))

INSERT INTO @TableA(USERID,HID,SomeData) SELECT 1,5,'Now'
INSERT INTO @TableA(USERID,HID,SomeData) SELECT 2,5,NULL
INSERT INTO @TableA(USERID,HID,SomeData) SELECT 3,5,NULL

INSERT INTO @Tableb(USERID,HID,SomeData) SELECT 2,4,'Now-1'
INSERT INTO @Tableb(USERID,HID,SomeData) SELECT 2,3,'Now-2'
INSERT INTO @Tableb(USERID,HID,SomeData) SELECT 3,4,'Now-1'

SELECT
    t1.USERID, T1.Hid AS [Current HID]
    ,
        CASE
            WHEN T1.SomeData IS NOT NULL THEN T1.SomeData
            WHEN T2.USERID IS NOT NULL THEN T2.SomeData
            WHEN T3.USERID IS NOT NULL THEN T3.SomeData
            ELSE T1.SomeData
        END AS [Most Recent SomeData]
FROM @TABLEA T1
LEFT JOIN @TABLEB T2 ON T2.USERID = T1.USERID AND T2.HID = T1.HID
LEFT JOIN @TABLEB T3 ON T3.USERID = T1.USERID AND T3.HID = T1.HID-1
Sign up to request clarification or add additional context in comments.

Comments

1

You were on the right track by using a case statement but it was just a little out of order. Warning! I didn't test it but I believe I ran into something similar in the past.

SELECT      T1.*
            ,T2.*
FROM        TABLEA  t1
LEFT JOIN   TABLEB  t2  ON      T2.USERID = T1.USERID
                            AND T2.HID =    CASE
                                                WHEN T2.HID = T1.HID then t1.hid
                                                else T1.HID - 1
                                            end

3 Comments

Your solution worked reducing NULLS but allowed duplicates so I got double the results.
Would adding distinct solve the dupes? Without test data, I can’t tell.
Yes I just did! Switched the LEFT JOIN for a INNER but I still need to manually check data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.