SQL Create View - Sum Transactions on one line - sql

I want to create a view, whereby all post stock transactions will post on one line, as per my SQL Statement below, I get all transactions, but each is on a new line. I want the arrangement to be each new stock item on a new line, with "QtyOnHand" as the next column. Then I need all the QtyOut transactions to sum up in one column and all QtyIn to sum in another. Is this possible?
SELECT
StkItem.ItemGroup
,StkItem.Qty_On_Hand AS QtyOnHand
,PostST.TrCodeID
,PostST.Description
,PostST.Quantity
,PostST.Reference
,PostST.Order_No
,PostST.fQuantityInvoiced
,PostST.QuantityR
,PostST.TxDate
,PostST.Debit
,PostST.Credit
,Concat(StkItem.Description_1, ' - ',StkItem.Code) AS ItemAndCode
FROM PostST
INNER JOIN StkItem
ON StkItem.StockLink = PostST.AccountLink
The below picture shows how this statement currently shows - you can see on the far right how the same stock code is repeated for each transaction, as I would rather the stock item show once, and the transactions be summed.
This data will be dumpted into Excel and then used to create a stock turnover report.
Thank you!

You have to use SUM() and GROUP BY. Maybe that is what you need
SELECT
StkItem.ItemGroup
,SUM(StkItem.Qty_On_Hand) AS QtyOnHand
,PostST.TrCodeID
,PostST.Description
,SUM(PostST.Quantity) as Quantity
,PostST.Reference
,PostST.Order_No
,SUM(PostST.fQuantityInvoiced) as fQuantityInvoiced
,SUM(PostST.QuantityR) as QuantityR
,PostST.TxDate
,SUM(PostST.Debit) as Debit
,SUM(PostST.Credit) as Credit
,Concat(StkItem.Description_1, ' - ',StkItem.Code) AS ItemAndCode
FROM PostST
INNER JOIN StkItem
ON StkItem.StockLink = PostST.AccountLink
GROUP BY
StkItem.ItemGroup
,PostST.TrCodeID
,PostST.Description
,PostST.Reference
,PostST.Order_No
,PostST.TxDate
,StkItem.Description_1
,StkItem.Code

Related

Eloquent sum of derived column in select and also where clause

I have a table sales which has a related receipts table.
A sale can have many receipts. If the sum of the receipts is less than the sales amount then there is a balance outstanding.
I have the SQL that works just how I want. Having headaches trying to shoehorn this into eloquent.
SELECT `sales`.`id`, `sales`.`created_at`,`sales`.`updated_at`,`sales`.`sales_date`,`sales`.`gross`, `sales`.`net_amount`,`sales`.`vat_amount`,`sales`.`vat_rate`,`sales`.`description`,
(SELECT SUM(receipt_gross_amount) as received_gross FROM `receipts` INNER JOIN `sales` WHERE `receipts`.`sales_id` = `sales`.`id`) as received
FROM `sales`
) as unsettled_invoices
WHERE unsettled_invoices.gross > COALESCE(unsettled_invoices.received,0)
I won't bore you with what I have tried already as it's not relevant and just causes php to hang and issue "killed" in the command line...
This seems to do the job ...
$unsettledsalessentries = DB::table('sales')
->leftjoin('receipts', 'sales.id','=', 'receipts.sales_id')
->select('sales.id','sales.gross','sales.description',DB::raw('SUM(COALESCE(receipts.receipt_gross_amount,0)) as total_receipts'))
->groupBy('sales.id','sales.gross','sales.description')
->havingRaw('sales.gross > total_receipts')
->get();

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: How to retrieve a certain field from a table and return it?

Background
I am currently working on a simple access database for a small bookstore. The business sells books as well as other items.
See following ER-diagram here
Problem
My problem starts in the table Transaction. I would like to create a simple form where a subtotal is calculated as quantity purchased multiplied by the price (both of a certain item).
However the Price field is either in the BookInfo, FoodAndBev, or ApparelAndSupplies table.
Question
How can I traverse the Transaction table to Items and to one of the tables I listed depending on the StockNum in Transaction?
For example, a customer buys an item with StockNum BK001. I would like to retrieve the Price corresponding to BK001 in the BookInfo table and return to Transaction to be used for calculating the subtotal.
The field StockNum exists in tables BookInfo, FoodAndBev, and ApparelAndSupplies.
Sample Data: BookInfo, Items, Transaction
Ideal Output: Transaction 1: A customer buys 2 copies of a book with StockNum 'BK001' (disregard what I already have in the screenshot). The Price of 'BK001' is $119.99 which I would need to retrieve from BookInfo (my problem is I want to make sure it goes to BookInfo not the other two tables which have StockNum also), so the subtotal would then be calculated and would show $239.98. For now, I've been doing this manually. I want to be able to do this with different StockNum such as those that start with AS for Apparel and Supplies and FB for food and beverage.
Thanks in advance!
Left-Joining all tables and using Case-When-Expression (which is function switch in Access) for different price multiplication:
SELECT t.StockNum, t.NumOrdered,
switch(
Left(t.StockNum,2) = 'BK' , (t.NumOrdered * b.Price),
Left(t.StockNum,2) = 'AS' , (t.NumOrdered * a.Price),
Left(t.StockNum,2) = 'FB' , (t.NumOrdered * f.Price),
) AS subtotal
FROM Transaction t
LEFT JOIN BookInfo b ON b.StockNum = t.SockNum
LEFT JOIN ApparelAndSupplies a ON a.StockNum = t.SockNum
LEFT JOIN FoodAndBev f ON f.StockNum = t.SockNum

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 to report on what invoices have not been paid, ordered by invoice number

new to SQL and only been doing it for a week and a half. So I apologise now for the question being simple or appearing to be stupid.
I want to present a report on invoices that have not been paid by a given date, ordered by invoice number.
This is how I have displayed, the paid invoices but without the given date.. How do I display, the invoices that have not been paid by say 31-MAR-14.
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE, PAYMENT
WHERE INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
ORDER BY INVOICE.INVOICE_NUMBER;
SELECT PAYMENT.PAYMENT_NO
FROM INVOICE, PAYMENT
WHERE INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
AND INVOICE.INVOICE_DATE = 'AAAAMMJJ'
ORDER BY INVOICE.INVOICE_NUMBER;
Try something like this.
I have question. How do you say the invoice are not paid ?
You need to join the two tables together with a LEFT JOIN, then look to see where the payment date is > 31-MAR-14. Try something like this:
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE
LEFT JOIN PAYMENT ON INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
WHERE PAYMENT.Date_of_payment > '3/31/2014'
ORDER BY INVOICE.INVOICE_NUMBER;
This looks for all payments that were made after 3/31/2014. You may need to add another condition, that limits what invoices you're looking for.
To check payments that have not been made, look where any field in the PAYMENT table is null. SQL like this:
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE
LEFT JOIN PAYMENT ON INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
WHERE INVOICE.INVOICE_DATE = '3/31/2014'
AND PAYMENT.PAYMENT_NO IS NULL
ORDER BY INVOICE.INVOICE_NUMBER;
LEFT JOIN in this case will always return values for the INVOICE table, but may return NULL values in place of the PAYMENT if a payment has not been entered yet. Checking AND PAYMENT.PAYMENT_NO IS NULL will tell you that a payment has not been made yet.