Calculate within multiple where clause mysql - mysql

I have database structure as shown in the picture (it's simplified)
so now i want to calculate products in all stocks so that the result looked like (this assuming that store table has two records of store1 and store2):
if this is not possible this format is acceptable too
The main problem is that i can't figure out how should i calculate current stock for each store.
the curent stock for each stock = sum of all productin this stock
- sum of all productout this stock
+ sum of all producttransfer with transfertype=0 in this stock
- sum of all producttransfer with transfertype=1 in this stock
so how should i calculate it for each store when store number is not fixed

I think it should work, I'm writting it on the go so can't be 100% sure and there might be some typos
select A1.ProductID, A1.storehouseID, (SUM(IN)-SUM(OUT)) as quantity
from (
Select AD.productID, A.storehouseID, SUM(AD.Quantity) as IN
from actions A inner join productIN PI on A.ID = PI.ID
inner join actiondetails AD on PI.ID = AD.ID
group by AD.productID, A.storehouseID
UNION
select AD.ProductID, A.storehouseID, SUM(AD.Quantity)
from actions A inner join ProductTransfers T on A.ID = T.ID
inner join actiondetails AD on A.ID = AD.ID
where transferType = 0
group by AD.ProductID, A.storehouseID) as A1
inner join
(select AD.productID, A.storehouseID, SUM(AD.Quantity) as Out
from actions A inner join ProductOut PO on A.ID = PO.ID
inner join actiondetails AD on AD.ID = A.ID
group by AD.ProductID, A.storehouseID
UNION
select AD.productID, A.storehouse.ID, SUM(AD.Quantity) as Out
from actions A inner join ProductTransfers T on A.ID = T.ID
inner join actiondetails AD on AD.ID = A.ID
where TransferType = 1
group by AD.ProductID, A.storehouseID) as A2
on A1.ProductID = A2.ProductID and A1.storehouseID = A2.storehouseID
group by A1.ProductID, A1.StorehouseID

Related

Join three tables with group by to get counts

I have three tables- Ad(Id,AgentId,AdDesc,AdTitle,EmailId,ADate), AdComment(ComId,email,comment,AdId) and MyLikes(LikeId,email,AdId). Here I have to join three tables and display Ad table's all fields along with number of comments from AdComment table based on every Ad Id(Ad.Id=AdComment.AdId) and number of likes from MyLikes based on a given email for every Ad Id(Ad.Id=MyLikes.AdId).
When I just joined Ad and Ad comment I used -
SELECT * , (
SELECT COUNT( c.AdId )
) AS ComCount
FROM Ad a
LEFT JOIN AdComment c ON a.Id = c.AdId
GROUP BY a.Id
ORDER BY a.Id DESC
This is working fine.
Also when I joined Ad and MyLikes I used -
SELECT a.Id, (
SELECT COUNT( * )
FROM MyLikes m
WHERE (
m.email = 'nik#gmail.com'
AND m.AdId = a.Id
)
) AS MyCount
FROM Ad a
LEFT JOIN MyLikes m ON a.Id = m.AdId
GROUP BY a.Id
This is working fine.
But when I tried all three table join it is not working, gives some wrong value for comment count.
For this I used-
SELECT a.Id,a.AgentId,a.EmailId,a.AdTitle,a.AdDesc, (
SELECT COUNT(m.AdId)
FROM MyLikes m
WHERE (
m.email = 'nik#gmail.com'
AND m.AdId = a.Id
)
) AS MyCount,(
SELECT COUNT( c.AdId )
) AS ComCount
FROM Ad a
LEFT JOIN MyLikes m ON a.Id = m.AdId LEFT JOIN AdComment c ON a.Id = c.AdId
GROUP BY a.Id ORDER BY a.Id DESC
How can I join these three tables and get the desired result.
Assuming I'm understanding your question correctly, here's one option using subqueries to count your data in the joins instead:
select a.Id, a.AgentId, a.EmailId, a.AdTitle, a.AdDesc,
b.AdIdCount, c.AdIdCount
from Ad a
left join (select AdId, count(*) AdIdCount
from AdComment
group by AdId) b ON a.Id = b.AdId
left join (select AdId, count(*) AdIdCount
from MyLikes
where email = 'nik#gmail.com'
group by AdId) c ON a.Id = c.AdId
If you prefer correlated subqueries, then this should work:
select a.Id, a.AgentId, a.EmailId, a.AdTitle, a.AdDesc,
(select count(*)
from AdComment b
where a.Id = b.AdId),
(select count(*)
from MyLikes c
where c.email = 'nik#gmail.com' and
a.Id = c.AdId)
from Ad a
Assuming that LikeID and ComId are the unique id fields of the MyLikes and AdComment tables then you should be able to just use a pair of joins and count the distinct id fields from each table:-
SELECT a.Id,
a.AgentId,
a.EmailId,
a.AdTitle,
a.AdDesc,
COUNT(DISTINCT m.LikeId) AS MyCount,
COUNT(DISTINCT c.ComId) AS ComCount
FROM Ad a
LEFT OUTER JOIN MyLikes m ON m.email = 'nik#gmail.com' AND a.Id = m.AdId
LEFT JOIN AdComment c ON a.Id = c.AdId

MySQL - query ordered by date failing to get the latest record

I've got a database set up as follows:
http://sqlfiddle.com/#!9/2c5fc
What I'm looking to do is get a list of each store, and their last budget amount (Each schedule's total in the budget * their apportionment for that schedule / 100).
Some stores might not have apportionments set for the last budget, so I need the last budget where they have an apportionment set, or NULL if no apportionment has been set or no budget exists.
I've got the following SQL query:
SELECT s.StoreID,s.CentreID, budgetcalc.amount, budgetcalc.BudgetDate FROM store as s
LEFT JOIN centre on s.CentreID = centre.CentreID
LEFT JOIN (SELECT BudgetDate, SUM(sch.Amount*appt.Percentage/100) as amount, appt.StoreID from budget b
INNER JOIN schedule as sch on b.BudgetID = sch.BudgetID
INNER JOIN apportionment as appt on sch.ScheduleID = appt.ScheduleID
GROUP BY appt.StoreID, b.BudgetID
ORDER BY STR_TO_DATE(b.BudgetDate,'%d-%m-%y') DESC
) as budgetcalc on s.StoreID = budgetcalc.StoreID
GROUP BY s.StoreID
ORDER BY s.StoreID, STR_TO_DATE(budgetcalc.BudgetDate,'%d-%m-%y') DESC;
However this has the issue of not returning the last year, it will return a previous year seemingly at random regardless of the order in which I return the subquery.
It is difficult to work out from just the table declarations, but you need to get the latest budget date for each store, then join that against your sub query that gets the budget details for each store / budget.
Untested but something like this:-
SELECT s.StoreID,
s.CentreID,
budgetcalc.amount,
budgetcalc.BudgetDate
FROM store as s
LEFT OUTER JOIN centre ON s.CentreID = centre.CentreID
LEFT OUTER JOIN
(
SELECT appt.StoreID,
MAX(BudgetDate) AS latestBudgetDate
FROM budget b
INNER JOIN schedule as sch ON b.BudgetID = sch.BudgetID
INNER JOIN apportionment as appt ON sch.ScheduleID = appt.ScheduleID
GROUP BY appt.StoreID
) latest_budget
ON s.StoreID = latest_budget.StoreID
LEFT OUTER JOIN
(
SELECT BudgetDate,
appt.StoreID,
SUM(sch.Amount*appt.Percentage/100) as amount
FROM budget b
INNER JOIN schedule as sch ON b.BudgetID = sch.BudgetID
INNER JOIN apportionment as appt ON sch.ScheduleID = appt.ScheduleID
GROUP BY appt.StoreID, b.BudgetID
) as budgetcalc
ON latest_budget.StoreID = budgetcalc.StoreID
AND latest_budget.latestBudgetDate = budgetcalc.BudgetDate
ORDER BY s.StoreID,
budgetcalc.BudgetDate DESC;
With help from Kickstart, this is the answer that works:
SELECT s.StoreID,s.CentreID, SUM(sch.Amount*appt.Percentage/100) as amount, b.BudgetDate FROM store as s
INNER JOIN centre on s.CentreID = centre.CentreID
LEFT JOIN budget as b on b.BudgetID =
(
SELECT budget.BudgetID from budget
INNER JOIN schedule on budget.BudgetID = schedule.BudgetID
INNER JOIN apportionment on schedule.ScheduleID = apportionment.ScheduleID
where CentreID = s.CentreID AND apportionment.StoreID = s.StoreID
ORDER BY BudgetDate DESC limit 1
)
LEFT JOIN schedule as sch on b.BudgetID = sch.BudgetID
LEFT JOIN apportionment as appt on sch.ScheduleID = appt.ScheduleID AND appt.StoreID = s.StoreID
GROUP BY s.StoreID
ORDER BY s.StoreID ASC;

Fetching a price with INNER JOIN using 3 different variables

What I have been trying to achieve is to pull a price based on 3 different variables: brand_id, model_id, motor_id.
The design of the tables that I am working with:
The only issue is that when I add an INNER JOIN for databaseapp_lkp_prices I get a zero result set (fyi, there aren't any prices currently set so databaseapp_lkp_prices is an empty table)
I was expecting to see NULL in place of the price for the 48,000 records that exist when I don't add the databaseapp_lkp_prices INNER JOIN
My query is:
SELECT
a.brand,
b.model,
c.motor,
d.ecu_hardware_ver,
d.ecu_software_ver,
d.ecu_software_upg_ver,
d.ecu_brand,
d.ecu_type,
d.eprom,
d.eprom_desc,
d.`checksum`,
d.checksum16,
c.motor_hp * 1.2 AS motor_hp,
e.price,
c.motor_id,
c.model_id,
c.brand_id
FROM
databaseapp_brand AS a
INNER JOIN databaseapp_model AS b ON b.brand_id = a.brand_id
INNER JOIN databaseapp_motor AS c ON b.model_id = c.model_id
INNER JOIN databaseapp_ecu AS d ON d.motor_id = c.motor_id
INNER JOIN databaseapp_lkp_prices AS e ON c.brand_id = e.brand_id AND c.model_id = e.model_id AND c.motor_id = e.motor_id
ORDER BY
a.brand ASC,
b.model ASC
Anyone able to help me out with why I'm getting a zero result set when I try to look up the price.
Cheers!
Inner join requires match. No match no row. You should try LEFT JOIN instead of INNER JOIN for databaseapp_lkp_prices contribution.

Issue to get total amount while using inner join in MYSQL

I get an wrong TotalPrice from the ItemDetails table while join the taxdetails table.
Code 1:
select Distinct B.ID as BillId,
I.ID as ItemDetailId,
I.TotalPrice as ItemPrice,
T.Amount as TaxAmount from Bill B
inner join ItemDetails I on I.BillNoID = B.ID
inner join TaxDetails T on T.ItemDetailId = I.Id;
Refer below image,
While sum the TotalPrice and TotalTaxAmount on the same query i got an wrong TotalPrice result,
Code 2:
select Distinct B.ID as BillId,
SUM(I.TotalPrice) as TotalPrice,
SUM(T.Amount) as TotalTaxAmount from Bill B
inner join ItemDetails I on I.BillNoID = B.ID
inner join TaxDetails T on T.ItemDetailId = I.Id
group by B.ID;
Please refer below image,
Actual issue is as per taxdetails per itemdetail each row the rows become multiple so the totalprice get differs.
Expected Output for code 2 (i have listed the first row expected result) is,
Billid TotalPrice TotalTaxAmount
1 70 30
Try this,you have multiple items/bill, that is why you can't make inner join directly.Remove group by also.
select B.ID as BillId,
I.TotalPrice as TotalPrice,
T.Amount as TotalTaxAmount from Bill B
inner join
(
select BillNoID,SUM(TotalPrice) as TotalPrice from ItemDetails
group by BillNoID
)as I on I.BillNoID = B.ID
inner join
(
Select ItemDetailId,SUM(Amount) as Amount from TaxDetails
group by ItemDetailId
)as T on T.ItemDetailId = I.Id

Selecting from multiple tables that use the same joins

I'm not really sure how to explain what I need to do without an example, so I hope I can explain myself well enough!
Lets say I have the following tables in my MySQL database:
buyers
sellers
adverts
addresses
locations
object_addresses
The tables buyers, sellers and adverts are all "objects". They are associated with addresses by object_addresses which has object_type, object_id and address_id.
The addresses table has a location_id to associate it with a location.
What I ultimately want is to select all types of objects that are within a certain distance (by using a latitude and longitude I have on the locations table).
I don't have a problem with the distance calculation itself. However, I am having trouble selecting all "objects" along with their respective addresses/ locations (since they all make use of object_address).
I am able to do the following:
SELECT * FROM buyers as b
INNER JOIN object_addresses as oa on oa.ObjectId = b.Id
INNER JOIN addresses as a on oa.AddressId = a.Id
INNER JOIN locations as l on a.LocationId = l.Id
WHERE oa.ObjectType = 'buyer';
I'm having a hard time incorporating sellers and adverts into the statement above.
This is likely an simple answer, but I just can't see it tonight. Can anyone point me in the right direction?
SELECT * FROM buyers as b
INNER JOIN object_addresses as oa on oa.ObjectId = b.Id
INNER JOIN addresses as a on oa.AddressId = a.Id
INNER JOIN locations as l on a.LocationId = l.Id
WHERE oa.ObjectType = 'buyer'
union
SELECT * FROM sellers as s
INNER JOIN object_addresses as oa on oa.ObjectId = s.Id
INNER JOIN addresses as a on oa.AddressId = a.Id
INNER JOIN locations as l on a.LocationId = l.Id
WHERE oa.ObjectType = 'seller'
etc?
if you don't like that - basically, you need to include the address bits multiple times - so that each one can be linked to each object type...
Try this one using join on specific conditions oa.ObjectType = 'seller',oa.ObjectType = 'advert',oa.ObjectType = 'buyer' so only related result set will join
SELECT * FROM buyers as b
INNER JOIN object_addresses as oa on (oa.ObjectId = b.Id AND oa.ObjectType = 'buyer')
INNER JOIN advert as ad on (oa.ObjectId = ad.Id AND oa.ObjectType = 'advert')
INNER JOIN seller as s on (oa.ObjectId = s.Id AND oa.ObjectType = 'seller')
INNER JOIN addresses as a on oa.AddressId = a.Id
INNER JOIN locations as l on a.LocationId = l.Id
Other solution would be join all your table and then check the object type
SELECT * FROM buyers as b
INNER JOIN object_addresses as oa on (oa.ObjectId = b.Id )
INNER JOIN advert as ad on (oa.ObjectId = ad.Id )
INNER JOIN seller as s on (oa.ObjectId = s.Id )
INNER JOIN addresses as a on oa.AddressId = a.Id
INNER JOIN locations as l on a.LocationId = l.Id
WHERE oa.ObjectType IN('buyer' , 'advert' , 'seller')