Reputation: 135
OK guys last question on this topic (I HOPE).
What I need to do is sum fields from two different tables, add them together, and check whether this total is greater than that customers credit limit.
I have broken down my problem into smaller tasks so that I could try to come up with the overall solution. (These smaller codes work correctly for me, but when combined in the third piece of code, they sum incorrectly). First I have calculated the first summed field as shown:
--summmed open invoices
SELECT company, sum(unit_price * invoice_qty) as open_invoices
FROM
(SELECT arc.company, ard.unit_price, ard.invoice_qty, arc.credit_limit
FROM iqms.arprepost_detail ard, iqms.arprepost arp, iqms.arcusto arc
WHERE ard.arprepost_id = arp.ID
AND arp.arcusto_id = arc.ID)
GROUP BY company
ORDER BY company;
The figures in this are coming out correctly when summed, I have checked manually. Next I have summed the other field I need as shown:
--summed open orders
SELECT company, (sum (unit_price * total_qty_ord)) as total_open_orders
FROM
(SELECT arc.company, od.unit_price, od.total_qty_ord, arc.credit_limit
FROM iqms.arcusto arc, iqms.orders o, iqms.ord_detail od
WHERE od.orders_id = o.ID
AND o.arcusto_id = arc.ID
AND (od.cumm_shipped < od.total_qty_ord OR od.cumm_shipped IS NULL))
GROUP BY company
ORDER BY company;
Again these figures are coming out correctly on manual inspection.
What I need now is to add these two calculations together and check whether that figure is greater than the 'credit_limit' field for that customer. I have written code for this but the figures are coming out way over what they should (this code is given below).
--summmed open invoices + open orders
SELECT company, credit_limit,
round(sum(i_up * invoice_qty)) AS total_invoices,
round(sum (o_up * total_qty_ord)) AS total_orders,
round(sum(i_up * invoice_qty) + sum (o_up * total_qty_ord)) as overall_total
FROM
(SELECT arc.company, arc.credit_limit, ard.unit_price as i_up, ard.invoice_qty, od.unit_price as o_up, od.total_qty_ord
FROM iqms.arprepost_detail ard, iqms.arprepost arp, iqms.arcusto arc, iqms.orders o, iqms.ord_detail od
WHERE
ard.arprepost_id = arp.ID
AND arp.arcusto_id = arc.ID
AND od.orders_id = o.ID
AND o.arcusto_id = arc.ID
AND (od.cumm_shipped < od.total_qty_ord OR od.cumm_shipped IS NULL)
)
GROUP BY company, credit_limit
HAVING ((sum(i_up * invoice_qty)) + (sum (o_up * total_qty_ord)) > credit_limit)
ORDER BY company;
I'm not sure where I'm going wrong. Maybe its a simple fix or maybe there's something wrong with my logic. Any insight is greatly appreciated. Thanks a lot for the continued support.
Upvotes: 2
Views: 1863
Reputation: 69789
My First observation would be that you should be using explicit joins instead of implicit joins, implict joins are 20 years out of date
You can't combine your 2 queries as you have done because they are from different tables, doing so with implicit joins is causing a cross join. I think the most simple way to do this would be to use 2 left joins for each of the queries:
SELECT arc.Company,
arc.Credit_Lime,
COALESCE(Open_Orders, 0) AS Open_Orders,
COALESCE(Open_Invoices, 0) AS Open_Invoices
COALESCE(Open_Orders, 0) + COALESCE(Open_Invoices, 0) AS Total_Amount
FROM iqms.arcusto arc
LEFT JOIN
( SELECT o.arcusto_ID
SUM(od.unit_price * od.total_qty_ord) AS Open_Orders
FROM iqms.orders o
INNER JOIN iqms.ord_detail od
ON od.orders_ID = o.ID
WHERE od.Cumm_Shipped < od.Total_qty_Ord
OR od.Cumm_Shipped IS NULL
GROUP BY o.arcusto_ID
) openOrders
ON openOrders.Arcusto_ID = arc.ID
LEFT JOIN
( SELECT arp.arcusto_id,
SUM(Unit_Price * Invoice_Quantity) AS Open_Invoices
FROM iqms.arprepost_detail ard
INNER JOIN iqms.arprepost arp
ON ard.arprepost_id = arp.ID
GROUP BY arp.arcusto_id
) OpenInvoices
ON OpenInvoices.Arcusto_ID = arc.ID
WHERE COALESCE(Open_Orders, 0) + COALESCE(Open_Invoices, 0) > arc.Credit_Limit;
You could also UNION THE two queries as follows:
SELECT arc.Company,
arc.Credit_Lime,
SUM(COALESCE(Open_Orders, 0)) AS Open_Orders
FROM iqms.arcusto arc
LEFT JOIN
( SELECT o.arcusto_ID
SUM(od.unit_price * od.total_qty_ord) AS Open_Orders
FROM iqms.orders o
INNER JOIN iqms.ord_detail od
ON od.orders_ID = o.ID
WHERE od.Cumm_Shipped < od.Total_qty_Ord
OR od.Cumm_Shipped IS NULL
GROUP BY o.arcusto_ID
UNION ALL
SELECT arp.arcusto_id,
SUM(Unit_Price * Invoice_Quantity) AS Open_Invoices
FROM iqms.arprepost_detail ard
INNER JOIN iqms.arprepost arp
ON ard.arprepost_id = arp.ID
GROUP BY arp.arcusto_id
) OpenInvoices
ON OpenInvoices.Arcusto_ID = arc.ID
GROUP BY arc.Company, arc.Credit_Limit
HAVING SUM(Open_Orders) > arc.Credit_Limit;
But I think the first offers more flexibility in identifying whether credit limits are exceeded by Open_Orders or Open_Invoices
Upvotes: 1
Reputation: 67762
In this case since the two queries are distinct, I suggest you use UNION ALL:
SELECT company, SUM(open_invoices) total /*should rename the column in query 1*/
FROM ([QUERY1]
UNION ALL
[QUERY2])
GROUP by company
Upvotes: 1