SQL Table Joining issue - sql

I have a two tables: "invoice" as I and "Accounts Receivable" as AR.
AR table includes invoice issued (with id 0) and cash received (with id 4), while I table includes invoice amount column and adjustment column.
Apart from regular invoices and adjustments there are cases where adjustments were made to invoice and net affect is 0.00 on AR table. Plus sometimes, invoices are created and written off at invoice table before posting, so AR will have 0.00 amount in AR but I table has $100 in amount and -$100 in adjustment.
I am trying to create a query where it gives me invoice issued and cash received side by side and also create a new column that includes adjustment made for invoices with 0.00 balance in AR. Columns that might help:
AR.ID = unique ID
AR.ARinvnumber= Invoice number from Invoice table
Ar.Type= 0=invoice, 1 = payment received
Ar.Amount= ARamount saved from invoice
I.Id= unique ID
Invoice number = number of invoice
Invamount= Actual invoice amount
Inv Adjustment= Adjustment applied on invoice
Any idea how I can achieve that? I am able to match I and AR table and cash and AR from AR table
Select *
From (select ar.customerId, ar.customername,ar.invnumber ar.amount, i.invamout, i.invadjustment from Ar join I on ar.arinvnumber=i.invoicenumber where ar.artype=1) inv
join
select (select ar.customerId, ar.customername, ar.invnumber ar.amount, i.invamout, i.invadjustment from Ar join I on ar.arinvnumber=i.invoicenumber where ar.artype=1) cash
on inv.invnumber=cash.invnumber and inv.customerid=cash.customerid
after getting this, how can I include those invoices for whom adjustment were made but there was no AR because adjustment equals invoice amount.
Answer:
The following answer worked for me. Basically I wanted to include all the adjustments from invoice table including those ones which are not populated in AR table because the adjustments were made to clear client’s balance related to the work done after final invoice was issues. I used following query
Select *
From (select AR.ARInvnum as ARInvnum, AR.Arclientnumber as Aclient, sum(AR.Amount), I.Invoicenumber, sum(distinct(I.IAmount)), sum(I.IAdjust)
From AR.ARInvnum=I.Invoicenumber
Where ar.artype=0
Group by AR.ARInvnum, I.Invoicenumber, AR.Arclientnumber)AInvoice
Left join
(select AR.ARInvnum as PARInvnum, AR.Arclientnumber as PClient, sum(AR.Amount), I.Invoicenumber, sum (I.IAmount), sum(I.IAdjust)
From AR.ARInvnum=I.Invoicenumber
Where ar.artype=4
Group by AR.ARInvnum, I.Invoicenumber, AR.ARclientnumber)PInvoice
on
AInvoice.ARInvnum=PInvoice.PARInvnum
and
AInvoice.Aclient=PInvoice.PClient
Keep in Mind the Distinct clause in the first portion of the subquery removes any duplicates as well as sum them, so it will look like one summary related to particular invoice number. first portion of the subquery is summarizing based on the invoice issues and the adjustments related to the client. and second part is matching all payments received. I hope, this helps.

You need to include a limiting clause, also known as a where clause. MSDN documentation on select lays out the syntax as follows:
SELECT select_list [ INTO new_table ]
[ FROM table_source ] [ WHERE search_condition ]
[ GROUP BY group_by_expression ]
[ HAVING search_condition ]
[ ORDER BY order_expression [ ASC | DESC ] ]
Be aware, you will not need every expression to create a valid select statement. Also you do not need to join the same query to itself. Why not simplify by running the query by itself?
select
ar.customerId, ar.customername, ar.invnumber,
ar.amount, i.invamout, i.invadjustment
from Ar
join I on ar.arinvnumber=i.invoicenumber
where ar.artype=1
But your questions asks how to limit the results to only
those invoices for whom adjustment were made but there was no [account receivable]
Update your where clause to something like
where ar.artype=1 and i.adjustment is not null and i.adjustment = i.invamount
This will limit the results returned by the select statement to only those records that meet all three of the following criteria:
artype is equal to 1
adjustment is not null
adjustment is equal to invamount
If that result set is too narrow, tweak your where clause. I find it helpful to identify a single record that looks like other records I would like to find. Use that records unique identifier as a test for whether or not your query is working like you expect.

Related

Calculate differences between two columns of two different tables

I want to calculate the difference between purchase order amount and purchase invoice amount. But I am not able to fetch the purchase invoice amount i.e. "pi.grand_total" and hence also not able to fetch the difference of "(pi.grand_total - po.grand_total)" . Please help.Below is my query.
PO = Purchase Order
PI = Purchase Invoice
SELECT DISTINCT
po.name AS "PO #:Link/Purchase Order:120",
po.supplier AS "Supplier:Link/Supplier:120",
po.Company AS "Company:Data:120",
po.currency AS "Currency:Link/Currency:120",
po.base_grand_total AS "Grand Total:Currency:120",
po.status AS "Status:Data:120",
po.per_received AS "Per Received:Data:120",
CEILING(po.per_billed) AS "Per Billed:Data:120",
po.delivery_date AS "Delivery Date:Date:120",
pi.grand_total AS "Final PI Total:120",
(pi.grand_total - po.grand_total) AS "Amount Difference:120"
FROM
"tabPurchase Order" as po
LEFT JOIN "tabPurchase Invoice" as pi ON po.name = pi.parent
WHERE
po.per_received = 100
AND
CEILING(po.per_billed) < 100
ORDER BY po.delivery_date ASC
You are using LEFT JOIN. This means when your second table has no data which matches with your first table you will receive no data from second table but nonetheless your first table will return all of its data.
You probably should check your join condition. If you wanted to join these two tables the way you want then use NVL Function for pi.grand_total column. Because it is on the left join it could have a NULL value thus NULL minus po.grand_total will give you NULL. NVL function turns NULL values into intended values like NVL(pi.grand_total,0)
A good example how joins work

Access 2013 SQL, three tables, two using sum wrong results

Can someone please help me with this issue? I've scoured the Internet looking at dozens of examples, but i just can't find a solution that works.
I am using Access 2013. The problem is that I am trying to make a query that will highlight all part numbers from a supplier that either has customer back orders and/or overdue deliveries.
I am using three tables:
tbl_Inventory_Master which I require the part number, on hand stock value, and the supplier code.
For any back orders I need to join the tbl_Customer_Back_Order table as I need the count of back order lines and the sum of the back order quantity.
If the supplier has a late delivery, then I need to add the tbl_On_Order table showing the count of overdue deliveries and the sum of the overdue quantities.
The query is retrieving the data but the returned quantities are double what they should be.
SELECT
I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
COUNT (B.Part_Number) AS Back_Order_Count, SUM(B.Back_Order_Qty) as BO_Qty,
COUNT(O.Part_Number) AS Late_Deliveries_Count, SUM(O.Order_Qty) AS Late_Qty
FROM (tbl_Inventory_Master AS I
LEFT OUTER JOIN tbl_Customer_Back_Order AS B
ON I.Inventory_Part_Num = B.Part_Number)
LEFT OUTER tbl_On_Order AS O
ON I.Inventory_Part_Num = O.Part_Number
WHERE
I.Customer_Code = '274' AND
O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY I.Inventory_Part_Num, I.Description, I.On_Hand_Stock
For example, for the part number 2022940 I should have 10 back order lines and an overdue quantity of 43. Instead, the query is returning 20 back order lines and an overdue quantity sum of 86.
From the on order table I have three orders totaling 144 pieces, instead the query is returning 960.
Can someone please advise, as this is driving me crazy?
You are joining along unrelated dimensions, so you need to aggregate before joining:
SELECT I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
B.Back_Order_Count, B.BO_Qty,
O.Late_Deliveries_Count, O.Late_Qty
FROM (tbl_Inventory_Master AS I LEFT OUTER JOIN
(SELECT B.Part_Number, COUNT(*) as Back_Order_Count,
SUM(B.Back_Order_Qty) as BO_Qty
FROM tbl_Customer_Back_Order AS B
GROUP BY B.Part_Number
) as B
ON I.Inventory_Part_Num = B.Part_Number
) LEFT JOIN
(SELECT O.Part_Number, COUNT(O.Part_Number) AS Late_Deliveries_Count,
SUM(O.Order_Qty) AS Late_Qty
FROM tbl_On_Order AS O
WHERE O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY O.Part_Number
) as O
ON I.Inventory_Part_Num = O.Part_Number
WHERE I.Customer_Code = '274';
Notice the outer aggregation is no longer needed.

SQL Query: joining three tables to generate a Sales Report of Spend

I normally work with MySQL so not sure how to get a query to work on SQL.
I have 3 tables:
Table1
ODBC_ORDER_LINE_ALL
This contains ORDER_LINE_NETT_TOTAL and also the ORDER_LINE_ORDER_ID
Table 2
ODBC_ORDER_ALL
This contains the ORDER_ID and also the ORDER_ACCOUNT_ID
Table 3
ODBC_ACCOUNT
This contains the ACCOUNT_ACCID and some other information on the account we may need in the future, hence why we are adding it.
I am joining table 1,2,3 together using the above constraints.
What I want to be able to do is generate a Sales Report of Spend showing Account Number and Total Spend but I can't seem to get the syntax correct.
Any help much appreciated.
Here are the tables:
ODBC_ORDER_LINE_ALL
ORDER_LINE_ID
ORDER_LINE_ORDER_ID
ORDER_LINE_DATE
ORDER_LINE_MEDIACODE
ORDER_LINE_SOURCE
ORDER_LINE_PRODUCT_ID
ORDER_LINE_PRODUCT_CODE
ORDER_LINE_PRODUCT_NAME
ORDER_LINE_QUANTITY
ORDER_LINE_NETT_PRICE
ORDER_LINE_VAT_CODE
ORDER_LINE_VAT_RATE
ORDER_LINE_VAT
ORDER_LINE_NETT_TOTAL
ORDER_LINE_VAT_TOTAL
ORDER_LINE_GROSS_TOTAL
ORDER_LINE_UNIT_COST
ORDER_LINE_COST_CURRENCY
ORDER_LINE_COST_EXCHANGE_RATE
ORDER_LINE_TYPE
ORDER_LINE_STAGE
ORDER_LINE_STAGE_DATE
ORDER_LINE_INVOICE_ID
ORDER_LINE_INVOICE_DATE
ORDER_LINE_KIT_COMPONENT
ORDER_LINE_KIT_LINE_ID
ORDER_LINE_USER
ODBC_ORDER_ALL
ORDER_ID
ORDER_TYPE
ORDER_MEDIA_CODE_ID
ORDER_MEDIA_CODE
ORDER_MEDIA_SUBCODE
ORDER_TAKEN_BY
ORDER_DATE
ORDER_ACCOUNT_ID
ORDER_DELIVERY_ACCOUNT_ID
ORDER_SOURCE_ID
ORDER_SOURCE
ORDER_WEB_ORDER_ID
ORDER_MULTI_CLIENT_ID
ORDER_MULTI_CLIENT
ODBC_ACCOUNT
ACCOUNT_ACCID
ACCOUNT_ACC_TYPE
ACCOUNT_REF
ACCOUNT_TITLE
ACCOUNT_FORENAME
ACCOUNT_SURNAME
ACCOUNT_COMPANY_NAME
ACCOUNT_HOUSE_NAME
ACCOUNT_ADD1
ACCOUNT_ADD2
ACCOUNT_ADD3
ACCOUNT_ADD4
ACCOUNT_POSTCODE
ACCOUNT_COUNTRY
ACCOUNT_PHONE1
ACCOUNT_PHONE2
ACCOUNT_FAX1
ACCOUNT_FAX2
ACCOUNT_EMAIL
ACCOUNT_WEBSITE
ACCOUNT_PRICELIST_ID
ACCOUNT_MEDIACAMPAIGN_ID
ACCOUNT_CREATED_DATE
Assuming that the table names are 'Table 1' ODBC_Order_Line_All, 'Table 2' ODBC_Order_All, 'Table 3' ODBC_Account, then you simply need to join the three tables on the relevant joining columns, and sum the order line nett total entries for each account:
SELECT A.Account_AccID, SUM(L.Order_Line_Nett_Total) AS TotalSpend
FROM ODBC_Account AS A
JOIN ODBC_Order_All AS O ON A.Account_Acc_ID = O.Order_Account_ID
JOIN ODBC_Order_Line_All AS L ON O.Order_ID = L.Order_Line_Order_ID
GROUP BY A.Account_AccID;
However, while there is nothing but the Account_AccID selected from ODBC_Account, there is no actual need to select from the ODBC_Account table; you can join just the two tables, yielding a simpler query:
SELECT O.Order_Account_ID AS Acount_AccID, SUM(L.Order_Line_Nett_Total) AS TotalSpend
FROM ODBC_Order_All AS O ON A.Account_Acc_ID = O.Order_Account_ID
JOIN ODBC_Order_Line_All AS L ON O.Order_ID = L.Order_Line_Order_ID
GROUP BY Account_AccID;
There is nothing here that is different in MySQL from any other SQL DBMS, so your knowledge of MySQL should transfer directly.

SUM(a*b) not working

I have a PHP page running in postgres. I have 3 tables - workorders, wo_parts and part2vendor. I am trying to multiply 2 table column row datas together, ie wo_parts has a field called qty and part2vendor has a field called cost. These 2 are joined by wo_parts.pn and part2vendor.pn. I have created a query like this:
$scoreCostQuery = "SELECT SUM(part2vendor.cost*wo_parts.qty) as total_score
FROM part2vendor
INNER JOIN wo_parts
ON (wo_parts.pn=part2vendor.pn)
WHERE workorder=$workorder";
But if I add the costs of the parts multiplied by the qauntities supplied, it adds to a different number than what the script is doing. Help....I am new to this but if someone can show me in SQL I can modify it for postgres. Thanks
Without seeing example data, there's no way for us to know why you're query totals are coming out differently that when you do the math by hand. It could be a bad join, so you are getting more/less records than you expected. It's also possible that your calculations are off. Pick an example with the smallest number of associated records & compare.
My suggestion is to add a GROUP BY to the query:
SELECT SUM(p.cost * wp.qty) as total_score
FROM part2vendor p
JOIN wo_parts wp ON wp.pn = p.pn
WHERE workorder = $workorder
GROUP BY workorder
FYI: MySQL was designed to allow flexibility in the GROUP BY, while no other db I've used does - it's a source of numerous questions on SO "why does this work in MySQL when it doesn't work on db x...".
To Check that your Quantities are correct:
SELECT wp.qty,
p.cost
FROM WO_PARTS wp
JOIN PART2VENDOR p ON p.pn = wp.pn
WHERE p.workorder = $workorder
Check that the numbers are correct for a given order.
You could try a sub-query instead.
(Note, I don't have a Postgres installation to test this on so consider this more like pseudo code than a working example... It does work in MySQL tho)
SELECT
SUM(p.`score`) AS 'total_score'
FROM part2vendor AS p2v
INNER JOIN (
SELECT pn, cost * qty AS `score`
FROM wo_parts
) AS p
ON p.pn = p2v.pn
WHERE p2n.workorder=$workorder"
In the question, you say the cost column is in part2vendor, but in the query you reference wo_parts.cost. If the wo_parts table has its own cost column, that's the source of the problem.

outer query to list only if its rowcount equates to inner subquery

Need help on a query using sql server 2005
I am having two tables
code
chargecode
chargeid
orgid
entry
chargeid
itemNo
rate
I need to list all the chargeids in entry table if it contains multiple entries having different chargeids
which got listed in code table having the same charge code.
data :
code
100,1,100
100,2,100
100,3,100
101,11,100
101,12,100
entry
1,x1,1
1,x2,2
2,x3,2
11,x4,1
11,x5,1
using the above data , it query should list chargeids 1 and 2 and not 11.
I got the way to know how many rows in entry satisfies the criteria, but m failing to get the chargeids
select count (distinct chargeId)
from entry where chargeid in (select chargeid from code where chargecode = (SELECT A.chargecode
from code as A join code as B
ON A.chargecode = B.chargeCode and A.chargetype = B.chargetype and A.orgId = B.orgId AND A.CHARGEID = b.CHARGEid
group by A.chargecode,A.orgid
having count(A.chargecode) > 1)
)
First off: I apologise for my completely inaccurate original answer.
The solution to your problem is a self-join. Self-joins are used when you want to select more than one row from the same table. In our case we want to select two charge IDs that have the same charge code:
SELECT DISTINCT c1.chargeid, c2.chargeid FROM code c1
JOIN code c2 ON c1.chargeid != c2.chargeid AND c1.chargecode = c2.chargecode
JOIN entry e1 ON e1.chargeid = c1.chargeid
JOIN entry e2 ON e2.chargeid = c2.chargeid
WHERE c1.chargeid < c2.chargeid
Explanation of this:
First we pick any two charge IDs from 'code'. The DISTINCT avoids duplicates. We make sure they're two different IDs and that they map to the same chargecode.
Then we join on 'entry' (twice) to make sure they both appear in the entry table.
This approach gives (for your example) the pairs (1,2) and (2,1). So we also insist on an ordering; this cuts to result set down to just (1,2), as you described.