Search code examples
sqlt-sqljoinnested-sets

Problem joining tables in SQL


SELECT MID, FAD.FirstOpenedDate ,LCD.LastCloseDate
FROM mwMaster.dbo.Merchant M
JOIN        (
            SELECT MerchID, MIN(moddate) AS FirstOpenedDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID
            )   FAD ON FAD.MerchID = M.MerchID 
LEFT JOIN   (
            SELECT MerchID, MAX(moddate) AS LastCloseDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID
            )   LCD ON LCD.MerchID = M.MerchID
JOIN        (
            SELECT merchid ,avg(Transactions) ,avg(Profit) 
            FROM mwMaster.dbo.ResidualSummary RS
            WHERE RS.Date_Processed < LCD.LastCloseDate
            GROUP BY Merchid    
            )   R ON R.MerchID = M.MerchID 

I am having trouble performing the following join. I have run into this problem before and used temp tables but would like to find out what I am doing wrong. Basically the line that is not working is the 3rd to last. The "< LCD.LastClostDate" says that it cannot be bound. Is it possible to use the value from LCD which I created in a nested query above (in that query I used the M table in a similar way but I didnt run into any issue)? I am thinking becasue the LCD table is dynamically created here it cannot be used in the nested query but this is just my guess.

Any ideas?

On a side note I have also seen people using a CROSS and OVER. Not to farmiliar with how this works but may be applicable here?


Solution

  • I think though haven't tested you can just change your JOIN to a CROSS APPLY in SQL 2005+

    SELECT MID, FAD.FirstOpenedDate ,LCD.LastCloseDate
    FROM mwMaster.dbo.Merchant M
    JOIN        (
                SELECT MerchID, MIN(moddate) AS FirstOpenedDate
                FROM mwMaster.dbo.MerchantStatusHistory
                GROUP BY MerchID
                )   FAD ON FAD.MerchID = M.MerchID 
    LEFT JOIN   (
                SELECT MerchID, MAX(moddate) AS LastCloseDate
                FROM mwMaster.dbo.MerchantStatusHistory
                GROUP BY MerchID
                )   LCD ON LCD.MerchID = M.MerchID
    CROSS APPLY(
            SELECT merchid ,avg(Transactions) ,avg(Profit) 
            FROM mwMaster.dbo.ResidualSummary RS
            WHERE RS.Date_Processed < LCD.LastCloseDate
            GROUP BY Merchid    
            )   R ON R.MerchID = M.MerchID 
    

    But it might be easier to use CTEs

     WITH LCD AS (SELECT MerchID, MAX(moddate) AS LastCloseDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID),
      R AS (
                  SELECT merchid ,avg(Transactions) ,avg(Profit) 
                  FROM mwMaster.dbo.ResidualSummary RS
                       INNER JOIN LCD on 
                       LCD.MERCHID = RS.MERCHID
                  WHERE RS.Date_Processed < LCD.LastCloseDate
                  GROUP BY Merchid    
                )
    
    SELECT MID, FAD.FirstOpenedDate ,LCD.LastCloseDate
    FROM mwMaster.dbo.Merchant M
    JOIN        (
                SELECT MerchID, MIN(moddate) AS FirstOpenedDate
                FROM mwMaster.dbo.MerchantStatusHistory
                GROUP BY MerchID
                )   FAD ON FAD.MerchID = M.MerchID 
    LEFT JOIN LCD ON LCD.MerchID = M.MerchID
    LEFT JOIN R ON R.MerchID = M.MerchID