I am created the three tables and list in the following table structures.
1) th_sales_inventory:
id
user_id
invoice_date
increment
invoice_num
client_address
total
shiping
roundoff
company_id
status
created_date
updated_date
updated_by
created_by
Table Data:
2) th_product
id
cat_id
name
description
purchase_price
selling_price
image
company_id
status
created_date
updated_date
created_by
updated_by
Table Data:
3) th_sales_inventory_detail
id
product_id
sales_inventory_id
selling_price
qty
amount
Table Data:
I created the sales invoice and values stored in the respective tables. I want to get each product sales with the total quantity, total amount based on the invoice date.
I am using following MySQL query but I do not get the result correctly.
SELECT p.id as pid,p.name, SUM(sid.qty) as sqty, SUM(total) AS sum,sid.qty, SUM(sid.qty * p.purchase_price) as pu_sum
FROM th_sales_inventory as si
LEFT JOIN th_sales_inventory_detail as sid ON sid.sales_inventory_id = si.id
LEFT JOIN th_product as p ON sid.product_id = p.id
WHERE `invoice_date` LIKE '2018-03-%' AND si.company_id = '1'
GROUP BY sid.product_id
Output:
pid name sqty sum qty pu_sum
1 thaaimann 2.000 80.00 2.000 20.00000
2 tomoto1 15.000 340.00 2.000 150.00000
Related
Using mysql 7.0
Lets say I have two tables products, orders
orders
id | date | latest_product_name
1 | ... | NULL
products
id| order_id | name | created_at
1 | 1 | Ball | 2020-07-10
2 | 1 | Car | 2020-07-11
How can I generate a query that updates order's latest_product_name column with Car in our case for order 1, because it was created at the latest date.
of course this would update every order with it's latest product
something like:
UPDATE orders SET latest_product_name = Latest.name
FROM (
SELECT p.name, DISTINCT(p.order_id) as order_id
FROM products as p
Order BY latest_file_date DESC
) as Latest
WHERE Latest.order_id = orders.id
Try the below way -
with cte as
(
SELECT name,order_id, row_number() over(partition by order_id order by created_at DESC) as rn
FROM products
)
UPDATE orders join cte
on cte.order_id = orders.id
SET latest_product_name = cte.name where rn=1
This query specifically retrieves the product that was added last
UPDATE orders SET latest_product_name =
(select prod_name
FROM products prods
where prods.order_id = orders.id
and prods.created_at = (select max(created_at)
from products prods_
where prods_.order_id = prods.order_id));
The following will achieve the same result, and is more compact, but perhaps not as logical
UPDATE orders SET latest_product_name =
(select prod_name
FROM products
order by created_at desc
limit 1
);
Se how both solutions work at this Fiddle
I'm having trouble writing an SQL statement to display a table showing names instead of IDs. I have the following 3 tables:
Item table
id price name stock
----------------------
1 0.99 Nuts 43
Customer table
id name
----------------------
1000 Bill
Purchase Table
id itemID Quantity custID
--------------------------------
100 1 1 1000
Essentially, I want a table that has the headings: Item Name, Item Price, Purchase Quantity and Customer Name
That's a pretty basic JOIN , you should read the SQL Tutorial about it
SELECT i.name,i.price,sum(p.quantity),c.name
FROM Item i
INNER JOIN Purchase p
ON(i.id = p.itemID)
INNER JOIN Customer c
ON(c.id = p.custID)
GROUP BY i.name,c.name
I have the following SQL tables, and require a solution compatible with both MySQL and Postgresql
create table price_level (
id serial primary key,
name varchar(200)
);
create table product (
id serial primary key,
name varchar(200),
base numeric not null,
vat int not null
);
create table product_price (
id serial primary key,
base numeric,
vat numeric,
product_id int not null references product(id) on update cascade on delete cascade,
price_level_id int not null references price_level(id) on update cascade on delete cascade,
unique(product_id,price_level_id)
);
For the SQL structure above I've created a view:
create view view_product as
select
p.id as product_id,
coalesce(pp.base, p.base) as base,
coalesce(pp.vat, p.vat) as vat,
pp.price_level_id
from
product as p
left join
product_price as pp on pp.product_id=p.id
;
These are sample data:
Table price_level
id name
1 A
2 B
3 C
4 D
5 E
Table product
id name base vat
1 Test 100 20
Table product_price
id base vat product_id price_level_id
1 NULL NULL 1 1
2 200 NULL 1 2
3 NULL 10 1 3
Output of the view view_product is:
product_id base vat price_level_id
1 100 20 1
1 200 20 2
1 100 10 3
... and the question is: How do I get output like this?:
product_id base vat price_level_id
1 100 20 1
1 200 20 2
1 100 10 3
1 100 20 4
1 100 20 5
As you see in the example above I need to get D and E price_level as additional rows. How do I create such view/join? It should have good performance also because tables can get big with additional price levels.
Thanks for help.
I would use union to add those records from price_level table that do not have corresponding record in product_price table for a certain product:
select
p.id as product_id,
coalesce(pp.base, p.base) as base,
coalesce(pp.vat, p.vat) as vat,
pp.price_level_id
from
product as p
left join
product_price as pp on pp.product_id=p.id
union distinct
select
p.id as product_id,
p.base,
p.vat,
pl.price_level_id
from
price_level pl
join
product as p
where (p.id, pl.id) not in (select product_id, price_level_id from product_price)
I would use following approach, cross join tables price_level and product. Then just lookup if override exists in product_price table.
SELECT
product.id as product_id,
IFNULL(product_price.base, product.base) as `base`,
IFNULL(product_price.vat, product.vat) as `vat`,
price_level.id as price_level_id
FROM price_level
CROSS JOIN product
LEFT JOIN product_price ON
product_price.price_level_id = price_level.id AND
product_price.product_id = product.id
WHERE product.id = 1
ORDER BY product.id, price_level.id
just remember to use product.id and not product_id in WHERE conditions
Try with:
create view view_product as
select
p.id as product_id,
coalesce(pp.base, p.base) as base,
coalesce(pp.vat, p.vat) as vat,
coalesce(pp.price_level_id,pl.id) --modified row
from
product as p
left join
product_price as pp on pp.product_id=p.id
LEFT JOIN price_level pl on pp.price_level_id=pl.id -- modified row
;
(not tested, but for sure you have to catch the price levels from the properly table)
I have two tables (well I have more but I simplify it some for this question)
Invoice
invoiceID 10
invoiceNo 1234
invoiceAmount 1000
invoiceStatus 2
Payments
paymentID 3
invoiceID 10
paymentAmount 500
paymentMethod 3
Now I need a query that gives me some values from table Invoice but also a calculation based on values from Payments for a certain invoiceID. What I would like to get is:
Invoice number, invoice amount and remaining amount to pay
-------------- --------------- -----------------------
1234 1000 500
Can you help me finish up the query with a subquery that actually works.
select i.invoiceNo as 'Invoice Number', i.invoiceAmount as 'Invoice amount' (i.invoiceAmount - totallyPayed) as reminingToPay
from Invoice i
left join Payments p on (p.invoiceID = i.invoiceID)
where
i.invoiceStatus = 2
and totallyPayed = (select sum(p.PaymentAmount) from Payments where p.paymentMethod in (1,2,3))
You could do:
SELECT i.invoiceNo AS 'Invoice Number',
i.invoiceAmount AS 'Invoice amount',
(i.invoiceAmount - COALESCE(p.totalPayed,0)) AS remainingToPay
FROM Invoice i
LEFT JOIN (
SELECT invoiceID,
SUM(paymentAmount) AS totalPayed
FROM payments
WHERE paymentMethod IN (1, 2, 3)
GROUP BY invoiceId
) p
ON p.invoiceID = i.invoiceID
WHERE i.invoiceStatus = 2
First you get the sum of paymentAmount from payments table for each invoiceID and then you join with your invoice table to get the remainingToPay.
My goal is to retrieve the recorded purchase price for an item on an accepted purchase order.
Purchase_Orders table contains metadata for the order, such as the order number and its status (e.g., 1 for accepted, 0 for declined).
Purchase_Ord_Contents table contains contents records, which are linked via foreign key to the parent purchase order on a shared index order_number)
For example: I have two orders in my database, one has been accepted and the other has been declined. The data is represented as follows:
=========================================
PURCHASE_ORDERS TABLE
=========================================
id | order_number | order_status
-----------------------------------------
1 PO_100 0
2 PO_101 1
3 PO_102 1
===================================================
PURCHASE_ORD_CONTENTS TABLE
===================================================
id | order_number | purchase_price | sku
---------------------------------------------------
1 PO_100 1.50 APPLE
2 PO_100 1.50 ORANGE
3 PO_101 2.00 APPLE
4 PO_101 2.00 ORANGE
5 PO_102 1.75 BANANA
The query should return rows 3, 4 and 5, since PO_101 was accepted, whereas PO_100 was declined and row 5 is not only the only record for the given SKU, it was also on an accepted order. I've tried a few different approaches, but I always seem to end up either leaving out parts that were on an unaccepted Purchase Order, or retrieving the wrong order_number for the lowest purchase_price.
Here is what I have thus far (not working properly)
SELECT a.*
FROM purchase_ord_contents AS a
JOIN (SELECT sku,
MIN(purchase_price) AS min_price
FROM purchase_ord_contents
GROUP BY sku) AS b
ON ( a.sku = b.sku
AND a.purchase_price = b.min_price )
WHERE a.order_number
IN (
SELECT order_number
FROM purchase_orders
WHERE order_status != 0
)
This query successfully returns the records from the purchase_ord_contents table, however it omits records of the lowest purchase_price that were on a Purchase Order with an order_status of 0.
Any guidance would be greatly appreciated, I am not very well versed in "advanced" SQL queries as you have probably determined by now. Thank you for your time and please do not hesitate to ask if I should provide any further information.
This could be what you are looking for:
SELECT sku, purchase_price, order_number
FROM (
SELECT MIN(purchase_price) AS purchase_price, sku
FROM purchase_ord_contents
JOIN purchase_orders USING (order_number)
WHERE purchase_orders.order_status = 1
GROUP BY sku
) AS min_sku_price -- this is the lowest sale price for each SKU
JOIN purchase_ord_contents USING (sku, purchase_price) -- gets all orders having sold a SKU at its lowest price
JOIN purchase_orders USING (order_number)
WHERE purchase_orders.order_status = 1
Notice this will return several rows for one given SKU if the lowest price for this SKU was offered in several orders.
If I understand correctly I think you want this:
SELECT po.order_number, poc.sku, min(poc.purchase_price)
FROM purchase_orders AS po
JOIN purchase_ord_contents AS poc ON poc.order_number = po.order_number
WHERE po.order_status != 0
GROUP by po.order_number, poc.sku
order by po.order_number, poc.sku