SQL Join table with calculated fields - mysql

I want to add another column to this query to show backorders that need to be processed.
Currently the table is showing all orders that have outstanding items and the in stock amount for each stock ref included.
I want to to add a field for suggested invoice amount.
I.e if the order qty is 5 , the invoice qty is 2 and the in stock qty is 2 then suggest to deliver 2.
if the instock amount was 100 then suggest to deliver 3.
My current attempt is below but I cant work out how to do the last bit.
I know i need to do (qtyOrdered-qtyinvoiced) but literally hit a brick wall.
SELECT
c.cus_name,
ol.orderLines_stockRef,
ol.orderLines_qtyOrdered,
ol.orderlines_qtyInvoiced,
pr.products_instock
FROM
cus c
JOIN
orderheader oh ON oh.orderHeader_customer = c.cus_id
JOIN
orderlines ol ON ol.orderLines_orderId = oh.orderHeader_id
JOIN
products pr ON ol.orderlines_stockref = pr.products_reference
WHERE
ol.orderLines_qtyOrdered <> ol.orderlines_qtyInvoiced
Current output :

Try this:
SELECT
c.cus_name,
ol.orderLines_stockRef,
ol.orderLines_qtyOrdered,
ol.orderlines_qtyInvoiced,
pr.products_instock,
(CASE WHEN ol.orderLines_qtyOrdered - ol.orderlines_qtyInvoiced > pr.products_instock
THEN pr.products_instock
ELSE ol.orderLines_qtyOrdered - ol.orderlines_qtyInvoiced) AS qtyToSend,
FROM
cus c
JOIN
orderheader oh ON oh.orderHeader_customer = c.cus_id
JOIN
orderlines ol ON ol.orderLines_orderId = oh.orderHeader_id
JOIN
products pr ON ol.orderlines_stockref = pr.products_reference
WHERE
ol.orderLines_qtyOrdered <> ol.orderlines_qtyInvoiced

Related

Mysql LEFT JOIN in combination with optional relation parent<->child table not working

I am having some troubles when combining left joins with optional values to group by.
In short we have
table child products: catalog
table parent relations - if it exists! contains parent child relations : catalog_product_relation
table warehouses : warehouses
table products and stock : wh_products
and we are trying to get the stock total qty, where
stock is stored by child products and needs to be summed per that
if a parent relation exists then we should group by and show that data
even simpler
for products without a parent: just sum qty (already works)
for products with a parent: then rollup and sum by the parent identifier
and preferably also get the data for the parent identifier from the catalog (ie the right name and sku)
I hope it is clear ... the query below is not working. Step 1 to me looked like just getting the parent ID in a column
and step 2 is to sum the qty's for simple products per simple product and for parent products sum it up for all child simple product but show the parent data
select c.sku as sku,
IFNULL(pr.parent_id, c.entity_id) as main_id,
c.type_id as type,
SUM(CASE WHEN (wh.code='LR') THEN FLOOR(wp.qty) ELSE 0 END) AS 'Loc1',
SUM(CASE WHEN (wh.code='LS') THEN FLOOR(wp.qty) ELSE 0 END) AS 'Loc2'
FROM catalog c,
wh_products wp,
warehouses wh
LEFT JOIN catalog_product_relation pr ON pr.parent_id = c.entity_id
WHERE c.entity_id = wp.product_id and wp.warehouse_id = wh.warehouse_id and wp.qty > 0
GROUP BY main_id
I would start by writing the JOINs correctly and aggregating by the columns in the SELECT:
SELECT c.sku as sku,
COALESCE(pr.parent_id, c.entity_id) as main_id, c.type_id as type,
SUM(CASE WHEN wh.code = 'LR' THEN FLOOR(wp.qty) ELSE 0 END) AS Loc1,
SUM(CASE WHEN wh.code = 'LS' THEN FLOOR(wp.qty) ELSE 0 END) AS Loc2
FROM catalog c LEFT JOIN
wh_products wp
ON c.entity_id = wp.product_id LEFT JOIN
warehouses wh
ON wp.warehouse_id = wh.warehouse_id AND wp.qty > 0 LEFT JOIN
catalog_product_relation pr
ON pr.parent_id = c.entity_id
GROUP BY c.sku, COALESCE(pr.parent_id, c.entity_id), c.type_id;
I'm not sure if this fixes your problems. Without sample data and desired results, it is a bit hard to follow the logic.

Multiple Filter inside SELECT SQL Statement

I'm writing a SQL Statement to get some values in a Recordset, which I'll use to transfer the result into TextBoxes on a Form in Excel. The tables involved are:
Customers -> CustomerId, FirstName, LastName, TelNumber
Invoice -> InvoiceId, CustomerId, CarModel, CarColor, CarPlate
Repairs -> RepairId, InvoiceId, TypeOfRepair, PartOfCar, Price
Services -> ServiceId, InvoiceId, Date, Status
When a Customer comes to the Garage, an Invoice is created, which is associated with this customer. An invoice can have many Repairs. The customer goes away without repairing the car, but the invoice is there. If the customer decides to repair the car, then a Service is created, which starts with the Status "working on it...". When the service is done, the status change to "Waiting for Check Out..."
I want to use a SQL Statement to retrieve the following Values (columns) for a specific InvoiceId:
CarModel, Color, Plate, CustomerName (FirstName LastName), PaintingTotalValue (where 'Painting' is one type in the column 'Type'), OtherTotalValue (total price of all the other types of repairs in this invoice), total price (total price, that is, painting + other ones).
I wrote the following, to get the values, but I don't know how to get the PaintingTotalValue and OtherTotalVAlue.
SELECT i.CarModel, i.Color, i.Plate, CONCAT(c.FirstName,' ',c.LastName) AS Name, FORMAT(SUM(r.Price),2) AS TotalPrice
FROM Services AS s INNER JOIN Invoices AS i ON s.invoiceId=i.invoiceId
INNER JOIN Repairs AS r ON s.invoiceId=r.invoiceId
INNER JOIN Customers AS c ON i.customerId=c.customerId
WHERE s.invoiceId = 15
Use CASE WHEN in your SELECT clause, to select the value that's conditional to the type:
SELECT
...
CASE WHEN r.Type = 'Painting' THEN r.Price ELSE 0 END PaintWorkPrice,
CASE WHEN r.Type <> 'Painting' THEN r.Price ELSE 0 END OtherWorkPrice,
FROM ...
That's one thing.
The other thing is that you're not selecting anything from the Services table, and making your query much more complicated than it needs to be.
If you can modify the schema, remove the ServiceId primary key field, and use Services.InvoiceId as a primary key instead: that will enforce the 1:1 relationship naturally.
FROM Repairs r
INNER JOIN Invoices i ON r.InvoiceId = i.InvoiceId
INNER JOIN Customers c ON i.CustomerId = c.CustomerId
The data you want to aggregate is granular to Repairs, so you select FROM that, and then move your way through the foreign keys up to Customers.
SELECT
i.CarModel
,i.Color
,i.Plate
,CONCAT(c.FirstName,' ',c.LastName) Name
,CASE WHEN r.Type = 'Painting' THEN r.Price ELSE 0 END PaintWorkPrice
,CASE WHEN r.Type <> 'Painting' THEN r.Price ELSE 0 END OtherWorkPrice
,r.Price
FROM Repairs r
INNER JOIN Invoices i ON r.InvoiceId = i.InvoiceId
INNER JOIN Customers c ON i.CustomerId = c.CustomerId
That's not aggregated yet: there's a record for each repair, for every invoice, under every customer that has an invoice. That part is the sub-query. If you have a parameter, that's where you use it.
WHERE i.InvoiceId = pInvoiceId
If you're just hard-coding an ID, that's where you do it too.
Now type SELECT q.* FROM ( on the line above, and ) q under the WHERE clause, then replace the q.* with the fields you're not aggregating - and aggregate the others. The result should be something like this:
SELECT
q.CarModel
,q.Color
,q.Plate
,q.Name
,SUM(q.PaintWorkPrice) PaintAmount
,SUM(q.OtherWorkPrice) OtherAmount
,SUM(q.Price) TotalAmount
FROM (
SELECT
i.CarModel
,i.Color
,i.Plate
,CONCAT(c.FirstName,' ',c.LastName) Name
,CASE WHEN r.Type = 'Painting' THEN r.Price ELSE 0 END PaintWorkPrice
,CASE WHEN r.Type <> 'Painting' THEN r.Price ELSE 0 END OtherWorkPrice
,r.Price
FROM Repairs r
INNER JOIN Invoices i ON r.InvoiceId = i.InvoiceId
INNER JOIN Customers c ON i.CustomerId = c.CustomerId
WHERE i.InvoiceId = 15
) q
GROUP BY
q.CarModel
,q.Color
,q.Plate
,q.Name

Inner join and left join not working as expected in mysql

I have 3 tables
table_supplier_bills - bill_id, supplier_id, date
table_supplier_bill_details - bill_id, product_id, quantity, rate
table_supplier_bill_payment_details - id, bill_id, payment_date, amount
I want to get all the bills with their bill_amount and paid_amount.
This is my query.
select
SB.bill_id,
SB.date, SB.supplier_id,
SUM(SBD.quantity * SBD.rate) as bill_amount,
COALESCE(SUM(SBPD.payment_amount), 0.00) as paid_amount
from table_supplier_bills SB
INNER JOIN
table_supplier_bill_details SBD
ON SB.bill_id = SBD.bill_id
LEFT JOIN table_supplier_bill_payment_details SBPD
ON SBD.bill_id = SBPD.bill_id
group by SBD.bill_id;
But this query doesn't give correct paid_amount if there are multiple rows in table_supplier_bill_details for a bill. in case of multiple rows query gives the paid_amount multiplied by as many rows are in table_supplier_bill_details for that table.
Can anyone help me what is wrong here?
Use a correlated query instead :
SELECT SB.bill_id,
SB.date,
SB.supplier_id,
SUM(SBD.quantity * SBD.rate) as bill_amount,
COALESCE((SELECT SUM(SBPD.payment_amount)
FROM table_supplier_bill_payment_details SBPD
WHERE SBD.bill_id = SBPD.bill_id ),0.00) as paid_amount
FROM table_supplier_bills SB
INNER JOIN table_supplier_bill_details SBD
ON SB.bill_id = SBD.bill_id
GROUP BY SBD.bill_id;

MYSQL - JOIN table filter not working

I have four table each table connected with some id kindly see the below query how I'm getting
SELECT
tax_rates.name,
IF( products.tax_method = 0, 'Inclusive', 'Exclusive') AS type,
IF((SUM(purchases.grand_total) > 0),(SUM(purchases.grand_total)),(SUM(purchase_items .subtotal))) AS total_amount,
IF((SUM(purchases.order_tax) > 0),(SUM(purchases.order_tax)),SUM(purchase_items .item_tax)) AS tax_amount
FROM tax_rates
LEFT JOIN purchases ON purchases.order_tax_id = tax_rates.id
LEFT JOIN purchase_items ON purchase_items.tax_rate_id = tax_rates .id
LEFT JOIN products ON products.id = purchase_items.product_id
WHERE purchases.warehouse_id = 1
GROUP BY tax_rates.id, products.tax_method
ORDER BY tax_rates.name desc LIMIT 0, 10
The above query didn't return any result but if I remove WHERE purchases.warehouse_id = 1 then it display the result. I don't know where I'm doing the mistake. Kindly correct me.
Sorry to tell about this I'm try to get purchase order tax and purchase Item tax
in particular store and date
Output
name type total_amount tax_amount
VAT #20% Inclusive 11005.2000 1834.2000
VAT #10% Inclusive 165.0000 15.0000
No Tax Exclusive 204771.4000 0.0000
GST #6% Exclusive 7155.0000 405.0000
GST #6% Inclusive 7155.0000 405.0000
Thank you
Data type? purchases.warehouse_id = '1'?
You should not add the condition in where clause, when you are using the field of the left join table. so remove the where clause and use like below
LEFT JOIN purchases ON purchases.order_tax_id = tax_rates.id and purchases.warehouse_id = 1
If you try to add the left join table field in where clause it will become INNER JOIN. hence it may not display any rows according to your data.

Splitting transaction order lines in two categories

I'm building a bookkeeping application for a friend that runs a shop-in-shop. Basically, every product is owned by a seller.
They want an overview where they can see the value of how much money in a transaction was paid for their products (owned by seller 1) and how much money went to other products (seller != 1).
Here's the ERD:
I tried the following query:
SELECT transaction.id, SUM(orderline.count), SUM(orderline.price), SUM(o1.price), SUM(o2.price), transaction.date
FROM transaction
JOIN orderline
ON orderline.transaction_id = transaction.id
JOIN product
ON product.barcode = orderline.product_barcode
JOIN orderline o1
ON o1.transaction_id = transaction.id AND o1.product_barcode IN (SELECT barcode FROM product WHERE seller_id = 1)
JOIN orderline o2
ON o2.transaction_id = transaction.id AND o2.product_barcode IN (SELECT barcode FROM product WHERE seller_id != 1)
GROUP BY transaction.id
Unfortunately, this only returns one transaction instead of all, and it doesn't return the correct sums of the prices either:
In for transaction 77, the value of SUM(o1.price) should be 4.5, and that of SUM(o2.price) should be 0.95. The value of SUM(orderline.price) is correct.
I would like to instead get all transactions, and then the total value, value of products owned by seller 1 and value of products owned by seller != 1 (products should be part of the transaction, of course).
SELECT TRANSACTION.id,
Sum(orderline.count),
Sum(orderline.price),
Sum( case when product.seller_id = 1 then orderline.price else 0 end ),
Sum( case when product.seller_id <> 1 then orderline.price else 0 end),
TRANSACTION.date
FROM TRANSACTION
JOIN orderline
ON orderline.transaction_id = TRANSACTION.id
JOIN product
ON product.barcode = orderline.product_barcode
GROUP BY TRANSACTION.id , TRANSACTION.date