Getting Quantity Mysql - mysql

QUERY 1(FIRST TABLE - STOCK IN)
select sum(s.liquid_quantity) as 'stock in total' from stockin_detail s
left join reagent r on r.id = s.reagent_id group by r.name
QUERY 2(SECOND TABLE - STOCK OUT)
select sum(t.consumption)as 'stock out total' ,r.name from stock_out s
inner join test_consumption t on s.consumption_id = t.id
inner join reagent r on r.id = t.reagent_id group by r.name
QUERY 1
stock in |r.name
100 |Reagent2
100 |Reagent3
QUERY 2
stock out |r.name
40 |Reagent2
20 |Reagent3
i tried doing this but it wont subtract because each of the nested select statement returns 'more than one column' error message due to group by.
I also tried removing the group by but ended up combing two different stocks then subtracted.
SELECT QUERY1 – QUERY2 as ‘current stocks’
EXPECTED OUT COME
current stock|r.name
60 |Reagent2
80 |Reagent3

Why not dump the two queries into inline views and then join them together?
Something like this should get you going. Inline view aliased 'i' is the stock in and inline view aliased 'o' is the stock out:
select i.name,i.in-ifnull(o.out,0) as 'current stock'
from
(
select sum(s.liquid_quantity) as in,r.name
from stockin_detail s
left join reagent r on r.id = s.reagent_id
group by r.name
) i
left outer join
(
select sum(t.consumption)as 'out' ,r.name from stock_out s
inner join test_consumption t on s.consumption_id = t.id
inner join reagent r on r.id = t.reagent_id
group by r.name
) o on i.name = o.name;

Related

Returning all results of an outer query and getting a count of attached items

So I'm struggling to write a query that returns me all categories regardless of what filter I have applied but the count changes based on how many returned recipes there will be in this filter.
This query works nice if I don't apply any filters to it. The count's seem right, but as soon as I add something like this: where c.parent_id is not null and r.time_cook_minutes > 60 I am filtering out most of the categories instead of just getting a count of zero.
here's an example query that I came up with that does not work the way I want it to:
select t.id, t.name, t.parent_id, a.cntr from categories as t,
(select c.id, count(*) as cntr from categories as c
inner join recipe_categories as rc on rc.category_id = c.id
inner join recipes as r on r.id = rc.recipe_id
where c.parent_id is not null and r.time_cook_minutes > 60
group by c.id) as a
where a.id = t.id
group by t.id
so this currently, as you might imagine, returns only the counts of recipes that exist in this filter subset... what I'd like is to get all of them regardless of the filter with a count of 0 if they don't have any recipes under that filter.
any help with this would be greatly appreciated. If this question is not super clear let me know, and I can elaborate.
No need for nested join if you move the condition into a regular outer join:
select t.id, t.name, t.parent_id, count(r.id)
from categories as t
left join recipe_categories as rc on rc.category_id = c.id
left join recipes as r on r.id = rc.recipe_id
and r.time_cook_minutes > 60
where c.parent_id is not null
group by 1, 2, 3
Notes:
Use left joins so you always get every category
Put r.time_cook_minutes > 60 on the left join condition. Leaving it on the where clause cancels the effect of left
Simply use conditional aggregation, moving the WHERE clause into a CASE (or IF() for MySQL) statement wrapped in a SUM() of 1's and 0's (i.e., counts). Also, be sure to consistently use the explicit join, the current industry practice in SQL. While your derived table uses this form of join, the outer query uses implicit join matching IDs in WHERE clause.
select t.id, t.name, t.parent_id, a.cntr
from categories as t
inner join
(select c.id, sum(case when c.parent_id is not null and r.time_cook_minutes > 60
then 1
else 0
end) as cntr
from categories as c
inner join recipe_categories as rc on rc.category_id = c.id
inner join recipes as r on r.id = rc.recipe_id
group by c.id) as a
on a.id = t.id
group by t.id
I believe you want:
select c.id, c.name, c.parent_id, count(r.id)
from categories c left join
recipe_categories rc
on rc.category_id = c.id left join
recipes r
on r.id = rc.recipe_id and r.time_cook_minutes > 60
where c.parent_id is not null and
group by c.id, c.name, c.parent_id;
Notes:
This uses left joins for all the joins.
It aggregates by all the non-aggregated columns.
It counts matching recipes rather than all rows.
The condition on recipes is moved to the on clause from the where clause.

mysql #1242 - Subquery returns more than 1 row

This is for my thesis and the dead end is later i don't know what i do wrong here .. Im hoping that someone can help me to know what's wrong here thanks
SELECT
flower_id,
flower_name,
flower_description,
flower_price,
flower_category,
(quantity - (SELECT
SUM(q.quantity_value)
FROM
orders_details od
INNER JOIN
cart_details cd ON cd.cart_id = od.cart_id
INNER JOIN
quantities q ON q.quantity_id = cd.quantity_id
WHERE
od.flag = 1 AND cd.flower_id = flower_id
GROUP BY cd.flower_id)) AS 'quantity',
mfg_date,
exp_date
FROM
flower_details,
categories
WHERE
flower_details.flower_category = categories.category_id
What im doing here is getting the total quantity of products from customer bought minus to inventory stocks
If your subselect return more then a rows you should join the sum using an inner join on subselect
If your subselect return more then a rows you should join the sum using an inner join on subselect inner join on subselect
SELECT
flower_details.flower_id,
flower_name,
flower_description,
flower_price,
flower_category,
flower_details.quantity - t1.quantity,
mfg_date,
exp_date
FROM flower_details
INNER JOIN categories ON flower_details.flower_category = categories.category_id
INNER JOIN (
SELECT cd.flower_id ,
SUM(q.quantity_value) AS quantity
FROM
orders_details od
INNER JOIN
cart_details cd ON cd.cart_id = od.cart_id
INNER JOIN
quantities q ON q.quantity_id = cd.quantity_id
WHERE
od.flag = 1 AND cd.flower_id = flower_id
GROUP BY cd.flower_id
) t1 on flower_details.flower_id = t1.flower_id

MySQL Help Cleaning Total Counts

Having an issue with a JOIN statement.
I'm trying to get a total per name, and not the current 1 with a ton of other same name records
SELECT a.`name`,
(SELECT COUNT(b.`id`)
FROM `host1_hosting` AS b
WHERE b.`id` = c.`host1_servers_host1_hosting_1host1_hosting_idb`) AS HostingCount
FROM `host1_servers` AS a
LEFT JOIN `host1_servers_host1_hosting_1_c` AS c ON c.`host1_servers_host1_hosting_1host1_servers_ida` = a.`id`
ORDER BY a.`name`
Example Returned
Name HostingCount
Name 1
Name 1
Name 1
Where it should be:
Name 3
I'm sure this is simple, but it's early monday, and I'm foggy
Query 2
SELECT a.`name`, COUNT(d.`id`)
FROM `host1_servers` AS a
JOIN `host1_servers_host1_hosting_1_c` AS c ON c.`host1_servers_host1_hosting_1host1_servers_ida` = a.`id`
JOIN `host1_hosting` AS d ON d.`id` = c.`host1_servers_host1_hosting_1host1_hosting_idb`
ORDER BY a.`name`
Gets me 1 name record, but a total of all COUNT
Your second query needs a group by:
SELECT a.`name`, COUNT(d.`id`)
FROM `host1_servers` AS a
JOIN `host1_servers_host1_hosting_1_c` AS c ON c.`host1_servers_host1_hosting_1host1_servers_ida` = a.`id`
JOIN `host1_hosting` AS d ON d.`id` = c.`host1_servers_host1_hosting_1host1_hosting_idb`
GROUP BY a.name
ORDER BY a.`name`;
Without the GROUP BY, MySQL interprets the query as an aggregation query to produce one row. The count() is the overall count. The column name is chosen arbitrarily from one of the rows (using a MySQL extension that wouldn't work in any other database).
EDIT:
If you want to keep all names from the first table and do the count, use left outer join:
SELECT a.`name`, COUNT(d.`id`)
FROM `host1_servers` a LEFT OUTER JOIN
`host1_servers_host1_hosting_1_c` c
ON c.`host1_servers_host1_hosting_1host1_servers_ida` = a.`id` LEFT OUTER JOIN
`host1_hosting` d
ON d.`id` = c.`host1_servers_host1_hosting_1host1_hosting_idb`
GROUP BY a.name
ORDER BY a.`name`;

mysql group by not doing what i am expecting?

SELECT
bp.product_id,bs.step_number,
p.price, pd.name as product_name
FROM
builder_product bp
JOIN builder_step bs ON bp.builder_step_id = bs.builder_step_id
JOIN builder b ON bp.builder_id = b.builder_id
JOIN product p ON p.product_id = bp.product_id
JOIN product_description pd ON p.product_id = pd.product_id
WHERE b.builder_id = '74' and bs.optional != '1'
group by bs.step_number
ORDER by bs.step_number, p.price
but here is my results
88 1 575.0000 Lenovo Thinkcentre POS PC
244 2 559.0000 Touchscreen with MSR - Firebox 15"
104 3 285.0000 Remote Order Printer - Epson
97 4 395.0000 Aldelo Lite
121 5 549.0000 Cash Register Express - Pro
191 6 349.0000 Integrated Payment Processing
155 7 369.0000 Accessory - Posiflex 12.1" LCD Customer Display
That's not how GROUP BY is supposed to work. If you group by a number of columns, your select can only return:
The columns you group by
Aggregation functions from other columns, such as MIN(), MAX(), AVG()...
So you'd need to do this:
SELECT
bs.step_number,
MIN(p.price) AS min_price, pd.name as product_name
FROM
builder_product bp
JOIN builder_step bs ON bp.builder_step_id = bs.builder_step_id
JOIN builder b ON bp.builder_id = b.builder_id
JOIN product p ON p.product_id = bp.product_id
JOIN product_description pd ON p.product_id = pd.product_id
WHERE b.builder_id = '74' and bs.optional != '1'
group by bs.step_number, pd.name
ORDER by bs.step_number, min_price
(MySQL allows a very relaxed syntax and will happily remove random rows for each group but other DBMS will trigger an error with your original query.)
Join to a sub select of the tables which only contain the min value of each group
In this example. the mygroup min(amt) returns the lowest dollar item for a group
I then join this back to the main table as a full inner join to limit the records only to that minimum.
Select A.myGROUP, A.Amt
from mtest A
INNER JOIN (Select myGroup, min(Amt) as minAmt from mtest group by mygroup) B
ON B.myGroup=A.mygroup
and B.MinAmt = A.Amt
Yes. Each different group key is returned only once. This problem is not easily solved. Run two distinct queries and combine results afterwards. IF this is not an option create a temporary table for the minimum price for each step join the tables in the query.

MySQL how do I not include duplicate rows when I use SUM and COUNT with multiple INNER JOINS?

SELECT SUM(case when p.status = 2 then p.value end) as 'val_accepted'
FROM
props AS p
INNER JOIN (p_contents AS pc
INNER JOIN contents AS c ON c.id = pc.library_id)
ON p.id = pc.prop_id
WHERE p.account_id = 3
GROUP BY (pc.library_id)
so, what's happening:
there are two p_contents that are associated with a prop. those two p_contents have the same library_id which points to a corresponding content.
So, the SUM of p.value is double what it should be because there are two p_contents that point to the same content
How do I not double SUM the p.value?
EDIT:
I figured out how to use DISTINCT, but I still need access to the inner columns...
SELECT c.name as 'library_name',
SUM(case when p.status = 2 then p.value end) as 'val_accepted',
FROM
props AS p
INNER JOIN
(
SELECT DISTINCT(pc.library_id), prop_id
FROM prop_contents AS pc
INNER JOIN
(
SELECT name, visibility, id, updated_at
FROM contents AS c
) as c
ON c.id = pc.library_id
)as pc
ON p.id = pc.prop_id
WHERE p.account_id = 3
GROUP BY (pc.library_id)
and now I get the error:
Unknown column 'c.name' in 'field list')
Here's one solution. First reduce the set to distinct rows in an derived table, then apply the GROUP BY to that result:
SELECT SUM(case when d.status = 2 then d.value end) as 'val_accepted'
FROM (
SELECT DISTINCT p.id, p.status, p.value, pc.library_id
FROM props p
INNER JOIN p_contents AS pc ON p.id = pc.prop_id
INNER JOIN contents AS c ON c.id = pc.library_id
WHERE p.account_id = 3) AS d
GROUP BY d.library_id
You use DISTINCT(pc.library_id) in your example, as if DISTINCT applies only to the column inside the parentheses. This is a common misconception. DISTINCT applies to all columns of the select-list. DISTINCT is not a function; it's a query modifier.