Combining Select Statements

Hi Folks.

I have two relatively simple select statements that on their own work perfectly and provide accurate results. However when I try to combine them using either a Union or mashing them into a single statement my results are way off and I'm not sure what I'm doing wrong (not very well versed in SQL).

Here are my individual working statements...

SELECT        receive.Name, SUM(recvcart.NetWght) AS SWeight, receive.RecvDate
FROM            master118.receive AS receive INNER JOIN
                         master118.recvcart AS recvcart ON receive.ID = recvcart.RecvID
WHERE        (receive.Code = 'RNY') AND (receive.AcctCode = 'RENT') AND (receive.Name = 'Good Customer') AND (receive.RecvDate BETWEEN '1685620800' AND '1685620800')
GROUP BY receive.RecvDate, receive.Name
SELECT        delivery.Name, SUM(delvcart.NetWght) AS CWeight, delivery.DelvDate
FROM            master118.delivery AS delivery INNER JOIN
                         master118.delvcart AS delvcart ON delivery.ID = delvcart.DelvID
WHERE        (delivery.Code = 'RNY') AND (delivery.AcctCode = 'RENT') AND (delivery.Name = 'Good Customer') AND (delivery.DelvDate BETWEEN '1685620800' AND '1685620800')
GROUP BY delivery.DelvDate, delivery.Name

Can you provide some sample data and expected results? They should also show the actual results you're getting and what the discrepancy is to the expected.

When run individually I get data that looks like this...

Name SWeight RecvDate
Good Customer 7008 1685620800


Name CWeight DelvDate
Good Customer 4575 1685620800

If I simply add a union in between the statements I get this...

Name SWeight RecvDate
Good Customer 4575 1685620800
Good Customer 7008 1685620800

If I try to combine the two statements into one like this...

SELECT        receive.Name AS Name, SUM(recvcart.NetWght) AS SWeight, receive.RecvDate, delivery.Name as Name, SUM(delvcart.NetWght) AS CWeight, delivery.DelvDate
FROM            master118.receive AS receive INNER JOIN
                         master118.recvcart AS recvcart ON receive.RcID = recvcart.RecvID CROSS JOIN
                         master118.delivery AS delivery INNER JOIN
                         master118.delvcart AS delvcart ON delivery.ID = delvcart.DelvID
WHERE        (receive.Code = 'RNY') AND (receive.AcctCode = 'RENT') AND (receive.Name = 'Good Customer') AND (receive.RecvDate BETWEEN '1685620800' AND '1685620800') AND 
                         (delivery.Code = 'RNY') AND (delivery.AcctCode = 'RENT') AND (delivery.Name = 'Good Customer') AND (delivery.DelvDate BETWEEN '1685620800' AND '1685620800')
GROUP BY receive.RecvDate, delivery.DelvDate, receive.Name, delivery.Name

I get this...
Name SWeight RecvDate Name CWeight DelvDate
Good Customer 189216 1685620800 Good Customer 146400 1685620800

If I try Select Distinct I get the same results. What I am looking to accomplish is this...

Name SWeight CWeight
Good Customer 7008 4575

Truth be told I don't really need to output the dates but was doing so for testing.

This should do it:

;WITH CTE(Name, Weight,Type) AS (
SELECT        receive.Name, SUM(recvcart.NetWght), 'R' Type
FROM            master118.receive AS receive INNER JOIN
                         master118.recvcart AS recvcart ON receive.ID = recvcart.RecvID
WHERE        (receive.Code = 'RNY') AND (receive.AcctCode = 'RENT') AND (receive.Name = 'Good Customer') AND (receive.RecvDate BETWEEN '1685620800' AND '1685620800')
GROUP BY receive.Name
UNION ALL
SELECT        delivery.Name, SUM(delvcart.NetWght), 'D' Type
FROM            master118.delivery AS delivery INNER JOIN
                         master118.delvcart AS delvcart ON delivery.ID = delvcart.DelvID
WHERE        (delivery.Code = 'RNY') AND (delivery.AcctCode = 'RENT') AND (delivery.Name = 'Good Customer') AND (delivery.DelvDate BETWEEN '1685620800' AND '1685620800')
GROUP BY delivery.Name)
SELECT Name, SUM(Case WHEN Type='R' THEN Weight END) SWeight,
SUM(Case WHEN Type='D' THEN Weight END) CWeight
FROM cte
GROUP BY Name
1 Like

I'd leave the dates in the combining query since your original queries allow a date range (although the specific query above uses a fixed date);


;WITH cte_receive AS (
    SELECT        receive.Name, SUM(recvcart.NetWght) AS SWeight, receive.RecvDate
    FROM            master118.receive AS receive INNER JOIN
                             master118.recvcart AS recvcart ON receive.ID = recvcart.RecvID
    WHERE        (receive.Code = 'RNY') AND (receive.AcctCode = 'RENT') AND (receive.Name = 'Good Customer') AND (receive.RecvDate BETWEEN '1685620800' AND '1685620800')
    GROUP BY receive.RecvDate, receive.Name
),
cte_delivery AS (
    SELECT        delivery.Name, SUM(delvcart.NetWght) AS CWeight, delivery.DelvDate
    FROM            master118.delivery AS delivery INNER JOIN
                             master118.delvcart AS delvcart ON delivery.ID = delvcart.DelvID
    WHERE        (delivery.Code = 'RNY') AND (delivery.AcctCode = 'RENT') AND (delivery.Name = 'Good Customer') AND (delivery.DelvDate BETWEEN '1685620800' AND '1685620800')
    GROUP BY delivery.DelvDate, delivery.Name
)
SELECT 
    ISNULL(cr.Name, cd.Name) AS Name, ISNULL(cr.RecvDate, cd.DelvDate) AS Date,
    SUM(cr.SWeight) AS SWeight, SUM(cd.CWeight) AS CWeight
FROM cte_receive cr
FULL OUTER JOIN cte_delivery cd ON cd.Name = cr.Name AND cd.DelvDate = cr.RecvDate
GROUP BY ISNULL(cr.Name, cd.Name), ISNULL(cr.RecvDate, cd.DelvDate)
ORDER BY Name, Date /*optional, of course*/
1 Like

Thank you both. I went with Robert's solution since it was easier for me to understand. Just for my own knowledge... if I'm understanding correctly you created a third query that wraps up the results of the original two in a single dataset. Is that accurate to say?

In this case, that's correct. The Common Table Expression (CTE) does a simple UNION ALL with your original 2 queries, with a slightly modified GROUP BY. The outer SELECT...FROM the CTE uses a CASE expression to SUM the weights for each type as separate columns.

1 Like