How can I get the quantity both expired and not yet expired? - mysql

I subtract the quantity of expired medicine to the actual stock. I use this (IFNULL(tbl_medicine.quantity - SUM(tbl_received.received_quantity),0)) AS Total and DATE(NOW()) > tbl_received.expiration_date to get the date of expired medicine. My problem is I can't get the quantity that is not expired yet. How can I get the quantity of not yet expired with expired medicine? Can somebody help me with my problem? Here's my query...
SELECT tbl_med.sup_med_id, tbl_med.quantity,
tbl_received.received_quantity, tbl_med.status,
(IFNULL(tbl_med.quantity - SUM(tbl_received.received_quantity),0)) AS Total
FROM
tbl_med
INNER JOIN
tbl_received ON tbl_received.sup_med_id = tbl_med.sup_med_id
WHERE
tbl_med.status = 'Active' AND DATE(NOW()) > tbl_received.expiration_date AND
tbl_med.barangay_id = 19
GROUP BY
sup_med_id HAVING Total > 0
ORDER BY
sup_med_id
output of query above
sup_med_id quantity received_quantity status Total
3 1800 1000 Active 800
7 1800 1000 Active 800
tbl_med & tbl_received table
id sup_med_id received_quantity expiration_date
1 3 1000 2019-09-04
2 7 1000 2019-09-04
3 9 1800 2022-09-04
medicine_id sup_med_id quantity status barangay_id
1 3 1800 Active 19
2 7 1800 Active 19
3 9 1800 Active 19
I want this to happen...
sup_med_id quantity received_quantity status Total
3 1800 1000 Active 800
7 1800 1000 Active 800
9 1800 1800 Active 1800
I just want to display the quantity to Total if the medicine is not expired yet

The issue comes from the fact you're only joining when the expiration date is in the past. To solve it that check should be removed from the WHERE clause and done in the SUM of expired quantities instead:
SELECT tbl_med.sup_med_id, tbl_med.quantity,
tbl_received.received_quantity, tbl_med.status,
(tbl_med.quantity
- SUM(CASE WHEN NOW() > tbl_received.expiration_date
THEN tbl_received.received_quantity
ELSE 0
END)
) AS Total
FROM
tbl_med
INNER JOIN
tbl_received ON tbl_received.sup_med_id = tbl_med.sup_med_id
WHERE
tbl_med.status = 'Active' AND
tbl_med.barangay_id = 19
GROUP BY
sup_med_id HAVING Total > 0
ORDER BY
sup_med_id
I haven't tested the query myself, but I believe it should achieve what you want

Related

How to get cumulative total for previous month and upto this month?

ID pcID contractor approver claimed
-------------------------------------------
1 1 one 1000 900
2 1 two 200 100
3 1 three 1000 1000
4 1 six 100 11
5 2 six 100 22
6 3 six 120 1
7 4 three 102 10
From the above table, I need to get cumulative amount for upto this month and previous month of approver and claimed and also current month approver, claimed amount based on the contractor. Like below table.
ID contractor approver claimed uptothisMTApprover uptothisMTClaimed previousMTApprover previousMTClaimed
-----------------------------------------------------------------------------------------------------------------
1 one 1000 900 1000 900 0 0
2 two 200 100 200 100 0 0
3 three 102 10 1102 1010 1000 1000
4 six 120 1 320 34 200 33
Thanks in advance..
You seem to want the latest row per contractor, as defined by pcID, and a cumulative sum of all previous months.
You can use window functions:
select contractor, approver, claimed,
total_approver as uptothisMTApprover,
total_claimed as uptothisMTClaimed,
total_approver - approver as previousMTApprover,
total_claimed - claimed as previousMTClaimed
from (
select t.*,
row_number() over(partition by contractor order by pcID desc) rn,
sum(approver) over(partition by contractor) total_approver,
sum(claimed) over(partition by contractor) total_claimed
from mytable t
) t
where rn = 1

The sum of Opening and Closing Balances for each Financial Year Grouped by Category in MYSQL

I have used three days attempting how to figure out this with no avail.I also did some search even from this forum but failed too.
It might look like Duplicate Question but to be honest this is different from others has been asked.
My question is how to get the sum of Balance Carry forward C/F and Closing balance for each financial year being GROUPED BY loan_id For each Date Range ie.Financial year?
transaction_t
Na loan_id date credit_amount debit_amount
1 1 2017-01-01 5,000 4,000
2 1 2017-05-01 6,000 2,000
3 2 2017-10-01 1,000 1,500
4 1 2018-10-30 2,000 400
5 2 2018-11-01 12,00 1,000
6 2 2019-01-15 1,800 500
7 1 2019-05-21 100 200
The above table schema and its data have mysql fiddle here I have also read this thread MySQL Open Balance Credit Debit Balance which is only working for single user.
So far I have tried:
SELECT loan_id,
SUM(credit)-(SELECT SUM(a.debit) FROM transaction_t a
WHERE a.transaction_date
BETWEEN '2019-01-01' AND '2020-12-31' AND a.loan_id = loan_id) AS OpeningBalance,
sum(credit),sum(debit),
(#OpeningBalance+SUM(credit))-SUM(debit) AS closing_balance
FROM transaction_t tr
WHERE transaction_date BETWEEN DATE('2019-01-01') AND DATE('2020-12-31')
GROUP BY loan_id
But the above is not giving correct results ,How do i get the results like these ones?
A: Query made for date between 2017-01-01 and 2018-12-31
loan_id opening_balance sum(credit_amount) sum(debit_amount) closing_balance
1 0 13,000.00 6,400.00 6,600.00
2 0 2,200.00 2,500.00 -300
B: Query made for date between 2019-01-01 and 2020-12-31
loan_id opening_balance sum(credit_amount) sum(debit_amount) closing_balance
1 6,600 100.00 200.00 6,500.00
2 -300 1,800.00 500.00 1,000
You are looking for conditional aggregation.
The key thing is that you need to start scanning the table from the beginning of the history in order to generate the initial balance. Then you just need to adjust the conditional sums:
Consider:
SET #start_date = '2017-01-01';
SET #end_date = '2018-12-31';
SELECT
loan_id,
SUM(CASE WHEN transaction_date < #start_date THEN credit - debit ELSE 0 END) opening_balance,
SUM(CASE WHEN transaction_date BETWEEN #start_date AND #end_date THEN credit ELSE 0 END) sum_credit,
SUM(CASE WHEN transaction_date BETWEEN #start_date AND #end_date THEN debit ELSE 0 END) sum_debit,
SUM(CASE WHEN transaction_date <= #end_date THEN credit - debit ELSE 0 END) closing_balance
FROM transaction_t
WHERE transaction_date <= #end_date
GROUP BY loan_id
In your DB Fiddle, this returns:
loan_id opening_balance sum_credit sum_debit closing_balance
1 0 13000 6400 6600
2 0 2200 2500 -300
And when changing the dates to 2020-2021:
loan_id opening_balance sum_credit sum_debit closing_balance
1 6600 100 200 6500
2 -300 1800 500 1000
NB: that was a well-asked question, that SO could use more of!

How can I fix my table to make a expiration of medicine?

I'm doing an inventory system of drug store. And now I'm trying to do the expiration of medicine. I want to show you my table. Maybe you have an idea of how to fix my tables. I put the expiration date in tbl_received_order. When I received a medicine it will insert into tbl_medicine. What if the customer bought 50 pieces of paracetamol or supplier_med_id is equal to 3. And after two months the medicine received will be expired. I use DATE(NOW()) > tbl_received_order.expiration_date to get all the expired medicine.
My problem is that the qty is not tally to rec_qty when the medicine expired. Just for below example, I have 100 pcs. on my initial inventory. But later on, 50 pcs. was sold. Why is it 100 pcs.is still reflecting on my inventory of medicines for expiration, instead of 50pcs. How can I fix my table? Can somebody help me with my problem?
The is my table
tbl_medicine
med_id supplier_med_id qty status branch_id
1 3 50 Active 1
2 7 100 Active 1
3 9 100 Active 1
tbl_received_order
received_id user_id purchase_order_id date_received
RO20190001 1 PO20190001 2019-05-04
tbl_received_order_details
id received_id supplier_med_id rec_qty expiration_date
1 RO20190001 3 100 2019-11-04
2 RO20190001 7 100 2019-11-04
3 RO20190001 9 100 2019-11-04
1 RO20190002 3 50 2019-11-04
2 RO20190002 7 50 2019-11-04
3 RO20190002 9 50 2019-11-04
tbl_transaction
transaction_id customer_id user_id transaction_date branch_id
0001 CU2018001 1 2019-09-04 1
0002 CU2018001 1 2019-09-04 1
0003 CU2018001 1 2019-09-04 1
tbl_transaction_details
details_id transaction_id supplier_med_id qty price total_price
1 0001 3 50 10.00 500
2 0002 3 10 10.00 100
3 0003 3 10 10.00 100
You can get the accurate quantity by using a JOIN.
SELECT orderd.expiration_date, orderd.rec_qty - SUM(trans.qty) AS inventory_left
FROM tbl_received_order_details AS orderd
JOIN tbl_transaction_details AS trans
ON orderd.supplier_med_id = trans.supplier_med_id
WHERE orderd.supplier_med_id = 3
AND orderd.expiration_date < '2019-11-05'
Join tbl_received_order_details and tbl_transaction_details using supplier_med_id.
Filter the records with medicine id '3' and an expiration date.
Since there can be more than 1 transaction for a particular medicine, we need to SUM the quantity sold and subtract it from total quantity to get what's left.
Update 1
Above query will get expired medicines for the ones sold. To get quantity left for all inventories sold, use GROUP BY.
SELECT orderd.expiration_date, orderd.rec_qty - SUM(trans.qty) AS inventory_left
FROM tbl_received_order_details AS orderd
JOIN tbl_transaction_details AS trans
ON orderd.supplier_med_id = trans.supplier_med_id
WHERE orderd.expiration_date < '2019-11-05'
GROUP BY orderd.supplier_med_id
UPDATE 2
To get all left inventories that are expired whether they are sold or not, use LEFT JOIN. COALESCE(trans.qty, 0) will return first NOT NULL value. So if a medicine is never sold, it will not have any entry in transaction table which will return qty as NULL. In such cases, we will subtract zero from rec_qty which in turn will get complete rec_qty as left overs.
SELECT orderd.expiration_date, orderd.rec_qty - SUM(COALESCE(trans.qty, 0)) AS inventory_left
FROM tbl_received_order_details AS orderd
LEFT JOIN tbl_transaction_details AS trans
ON orderd.supplier_med_id = trans.supplier_med_id
WHERE orderd.expiration_date < '2019-11-05'
GROUP BY orderd.supplier_med_id

mySQL view to show distict value and all pertaining rows beneath it

I am using mySQL. I have a table that is updated everyday based on our sku. The sku has duplicate values because there is a pricing tier associated with it. I need to create a view that will show all the rows but only 1 sku and the associated sku rows beneath it so i can export everyday for an update in magento. Magento does not allow duplicate sku's during an import. Here is an example:
sku _tier_price_qty _tier_price_price
013964223286 10 1
50 1
100 1
9332153001025 5 1
25 1
50 1
9332153001032 5 1
25 1
50 1
9332153001063 5 1
25 1
50 1
9332153001049 5 1
25 1
50 1
640420002569 5 1
25 1
50 1
640420002538 5 1
25 1
50 1
640420002521 5 1
25 1
50 1
Although this type of formatting might be better to handle in a reporting application this query should do what you want:
select
case when x.tier_qty is not null then t.sku else null end tier_qty,
t.tier_qty,
t.tier_price
from t
left join (
select sku, min(tier_qty) tier_qty
from t
group by sku
) x on t.sku = x.sku and t.tier_qty = x.tier_qty
order by t.sku, t.tier_qty;
http://www.sqlfiddle.com/#!9/3314bd/1
Can you try this?
select case when (select MIN(tier_qty) from products where sku = o.sku) = tier_qty
then sku
else null,
tier_qty,
tier_price
from products o
order by sku, tier_qty

mysql query items with the largest price increase

I have a table 'item_prices' with:
resource_id, avg_price, time_stamp, samples
Items gets a new average price inserted into the table every day. Old averages are not deleted.
How can I query the 10 items with the highest "percent increase in price" since yesterdays average? I would also like to check that the samples is > 10 to ensure accuracy.
to clarify "percent increase in price":
percent_increase = (todays_avg_price - yesterdays_avg_price) / yesterdays_avg_price
example
resource_id | avg_price | time_stamp | samples
1 450 1380526003 12
2 650 1380526002 2
3 980 1380526001 68
1 400 1380440003 24
2 700 1380440002 13
3 400 1380440001 38
1 900 1380300003 11
2 250 1380300002 8
3 300 1380300001 4
returns
resource id | percent_increase
3 1.45
1 0.125
select
today.resource_id,
(today.avg_price - yesterday.avg_price) / yesterday.avg_price as percent_increase
from
item_prices today,
item_prices yesterday
where today.resource_id = yesterday_resource_id
and DATE(FROM_UNIXTIME(today.timestamp)) = $today
and DATE(FROM_UNIXTIME(yesterday.timestamp)) = $yesterday
order by percent_increase desc
limit 10
This is a self join; apologies for the archaic join syntax, it's a bad habit I find hard to shake.
Please try the query below..
select top 1 resource_id,avg_price from item_Prices
group by resource_id,avg_price
having count(resource_id,avg_price)>
10 order by time_stamp