How to get 2 results from 3 tables with 1 mysql syntax - mysql

I have 3 tables like this
soft_id soft_name
1 Office
pu_id soft_id pu_quantity
1 1 10
2 1 20
3 1 30
own_id soft_id owner
1 1 Peter
2 1 Tommy
3 1 David
How can I have a result like this in one single mysql query
soft_id soft_name sum(pu_quantity) count(owner)
1 Office 60 3

Try this:
SELECT a.soft_id,
a.soft_name,
b.p_cnt AS quantity,
c.o_cnt AS owner_count
FROM soft a
INNER JOIN
(SELECT soft_id, SUM(pu_quantity) AS p_cnt FROM product GROUP BY soft_id
) b
ON a.soft_id = b.soft_id
INNER JOIN
(SELECT soft_id, COUNT(*) AS o_cnt FROM owner GROUP BY soft_id
) c
ON b.soft_id = c.soft_id
GROUP BY a.soft_id,
a.soft_name
SQLFiddle
Note: assuming that the table names are soft, product and owner respectively.

Try this
SELECT S.soft_id,S.soft_name,P.sum(pu_quantity),O.count(owner)
FROM Soft S INNER JOIN Product P ON S.soft_id = P.soft_id
Inner JOIN Owner O = P.soft_id = O.soft_id
Group By S.soft_id,P.soft_id,O.soft_id,S.soft_name

Related

Get count of unmapped records in a many-to-many table

I have 3 tables as such
Product
ProductID
ProductDetails
1
...
2
...
3
...
Vendor
VendorID
VendorDetails
1
...
2
...
3
...
ProductVendors
ProductID
VendorID
1
1
2
1
1
2
2
2
3
2
How would I go about finding the number of products that are not mapped to a specific vendor.
I tried:
SELECT
COUNT(pr.id) AS product_count
FROM
products pr
LEFT JOIN vendor_product_map vp ON
pr.id = vp.product
LEFT JOIN vendors vv ON
vp.vendor = vv.id
WHERE
vv.id = 3 AND vp.vendor IS NULL
but that doesn't seem right. Any help is appreciated
A simple not exists query should be sufficient:
select *
from products
where not exists (
select *
from vendor_product_map
where vendor_product_map.product = product.id
and vendor_product_map.vendor = 12345678
)

SQL count asset inventory

In sql help i have 3 tables, table one is asset table which is as follow
id
asset_code
asset_name
asset_group
asset_quantity
1
A001
computer
4
7
2
A002
keyboard
6
4
and another table is asset_allocation
id
asset_id
allocated_quantity
allocated_location
returned
1
1
2
IT office
no
2
2
1
main hall
yes
the last table is asset_liquidated which will present assets that are no longer going to be used
id
asset_id
liquidated_quantity
1
1
1
Now lets say that i have 7 computer out of which 2 are allocated but not returned and i have 4 keyboards out of which 1 is allocated and it is returned back and 1 computer is liquidated means it is never going to be used
so now here i want to join these 3 tables and find inventory of my current stock in hand.
Now this is the query now i need to add this
where asset_allocation.returned is enum no inside this query
SELECT id,asset_code, asset_name, asset_group, asset_quantity,allocated_quantity,liquidated_quantity,
asset_quantity - COALESCE(AA.allocated_quantity, 0) - COALESCE(AL.liquidated_quantity, 0) available_quantity
FROM asset A
LEFT JOIN (SELECT asset_id, SUM(allocated_quantity) allocated_quantity
FROM asset_allocation
GROUP BY asset_id) AA ON A.id = AA.asset_id
LEFT JOIN (SELECT asset_id, SUM(liquidated_quantity) liquidated_quantity
FROM asset_liquidated
GROUP BY asset_id) AL ON A.id = AL.asset_id;
I believe what you are looking for is adding WHERE returned = 'no' in your first JOIN like so:
SELECT id,asset_code, asset_name, asset_group, asset_quantity,allocated_quantity,liquidated_quantity,
asset_quantity - COALESCE(AA.allocated_quantity, 0) - COALESCE(AL.liquidated_quantity, 0) available_quantity
FROM asset A
LEFT JOIN (SELECT asset_id, SUM(allocated_quantity) allocated_quantity
FROM asset_allocation
WHERE returned = 'no'
GROUP BY asset_id) AA ON A.id = AA.asset_id
LEFT JOIN (SELECT asset_id, SUM(liquidated_quantity) liquidated_quantity
FROM asset_liquidated
GROUP BY asset_id) AL ON A.id = AL.asset_id;
That changes the available quantity for keyboard from 3 to 4 for me
your query:
vs. mine:

Required SQL Query

I have been stuck on this for sometime now.
I have the following SQL Tables:
department table
Id Name
1 DeptA
2 DeptB
3 DeptC
users table
Id Name Dept
101 Alice 2
102 Bob 3
alpha table
Id Uid Title
501 101 HELLO
502 102 HEY
503 101 SQL
beta table
Id Uid Title
601 101 HELLO1
602 101 HEY1
603 102 SQL1
Explanation:
There's basically a users table which has all the users.
Each user has a department (Dept field)
Each user has some records, linked to it with Uid, in alpha and beta tables.
The result I want:
DeptA DeptB DeptC
0 4 2
I want the count of records in alpha and beta combined, grouped by Dept of the users whose records are there in these tables.
Can someone help me with the SQL query?
As per your table structure I've used dept id for retrieving result otherwise I used dept name. You can also use COALESCE function if you get NULL
-- MySQL
SELECT SUM(CASE WHEN d.id = 1 THEN COALESCE(total, 0) END) dept_A
, SUM(CASE WHEN d.id = 2 THEN COALESCE(total, 0) END) dept_B
, SUM(CASE WHEN d.id = 3 THEN COALESCE(total, 0) END) dept_C
FROM department d
LEFT JOIN (SELECT u.dept
, COUNT(1) total
FROM users u
INNER JOIN (SELECT uid
FROM alpha
UNION ALL
SELECT uid
FROM beta) t
ON u.id = t.uid
GROUP BY u.dept ) p
ON d.id = p.dept;
Please check url http://sqlfiddle.com/#!9/020b2/1

how to compare the row of table 1 with the column of table 2

2 tables
product:
prod_id prod_name
1 Citrus-fruit
2 bread
3 margarine
4 Ready-Soup
5 Tropical-fruit
trans:
trans_id prod_1 prod_2 prod_3 prod_4
1 Citrus-fruit margarine Ready-Soup
2 bread margarine Tropical-fruit
3 Citrus-fruit bread margarine Tropical-fruit
4 bread Tropical-fruit
5 Citrus-fruit bread margarine Tropical fruit
So I want to compare prod_name = prod_1 and return prod_id, prod_name = prod_2 and return prod_id and so on
I tried a mysql query as
select product.prod_id from `product` ,'trans' where product.prod_name=trans.prod_1;
the above query doesn't work properly.
My expectation is:
prod_1 prod_2 prod_3 prod_4
1 3 4
2 3 5
1 2 3 5
2 5
1 2 3 5
and then convert above table into text file as:
1,3,4
2,3,5
1,2,3,5
2,5
1,2,3,5
Thank you
It is not clear what you are expecting.However, you can try that:
select * from product inner join trans on product.prod_name=trans.prod_1;
You should get back the elements that are matching.
If you want to translate the names with the products' ids, you will have to join the trans table with the product table once for each column
select p1.prod_id, p2.prod_id, p3.prod_id, p4.prod_id
from trans t1
left join
product p1
on t1.prod_1 = p1.prod_name
left join
product p2
on t1.prod_2 = p2.prod_name
left join
product p3
on t1.prod_3 = p3.prod_name
left join
product p4
on t1.prod_4 = p4.prod_name
order by t1.trans_id
The left join is required because in your sample table some products seem to be missing, so using inner joins would not return you all those rows with at least one product missing.
Edit
If you can't / don't want to add the commas at application level (which I would suggest) you can achieve the same by changing the query above like this
select trim(trailing ',' from concat_ws(',', coalesce(p1.prod_id, ''),
coalesce(p2.prod_id, ''),
coalesce(p3.prod_id, ''),
coalesce(p4.prod_id, '')
)
)
from trans t1
left join
product p1
on t1.prod_1 = p1.prod_name
left join
product p2
on t1.prod_2 = p2.prod_name
left join
product p3
on t1.prod_3 = p3.prod_name
left join
product p4
on t1.prod_4 = p4.prod_name
order by t1.trans_id;
You can see both version in action here

MySQL: get count value in joins and if else

In My application I want to display all my friends and no of cheque given and received
Table Transaction Table Friends
---------------------------- -----------------------------
id given_id rev_id amt id who_id whom_id who_name
----------------------------- -------------------------------
1 2 1 1k 1 1 2 sss
2 2 3 1k 2 3 2 fff
3. 3 2 2k 3 4 1 eee
4 1 2 2k 4 2 1 iii
----------------------------- ------------------------------
Result whom_id=2 name=iii -> Friends (sss,fff)
=> sss gives totally 1 cheque and
sss receives totally 1 cheque and
fff gives 1 cheque and
fff receives 1 cheque and
I tried This one..
SELECT
p.who_id,
p.who_name,
COUNT( r1.give_id ) ,
COUNT( r1.rec_id )
FROM
friends p
LEFT JOIN Transaction r1
ON p.who_id = r1.give_id OR p.who_id = r1.rec_id
WHERE
p.whom_id = 1
GROUP BY p.who_id
Please provide me the best way to do this....
You can do it like this
SELECT
f.who_name,
count(t.given_id) GivenTotal,
count(lt.rev_id) as RecievedTotal
from friends as f
left join transaction as t
on t.given_id = f.who_id
left join transaction as lt
on lt.rev_id = f.who_id
where f.whom_id = 2
group by t.given_id
Demo
Output
who_name | GivenTotal | RecievedTotal
----------------------------------
sss | 1 | 1
fff | 1 | 1
try this,
select
id,
count(given_id) as given,
count(rev_id) as reveive
from Friends
GROUP BY id;
and if you whant the difference between the two amounts try this
select
id,
count(given_id) as given,
count(rev_id) as reveive,
given-receive as diff
from Friends
GROUP BY id;
You can use HAVING with group by ,
instead
WHERE p.whom_id = 1
There are two ways to do this, both involve joining on the Transactions table twice.
You can use subqueries:
SELECT f.who_id,
f.who_name,
t1.TotalGiven,
t2.TotalRev
FROM friends f
LEFT JOIN
(
select count(t.given_id) TotalGiven, t.given_id
from Transactions t
group by t.given_id
) t1
ON f.who_id = t1.given_id
LEFT JOIN
(
select count(t.rev_id) TotalRev, t.rev_id
from Transactions t
group by t.rev_id
) t2
ON f.who_id = t2.rev_id
where f.whom_id = 2;
See SQL Fiddle with Demo.
Or you can just use a join with no subquery:
select f.who_id,
f.who_name,
count(t1.given_id) TotalGiven,
count(t2.rev_id) TotalRev
FROM friends f
LEFT JOIN Transactions t1
ON f.who_id = t1.given_id
LEFT JOIN Transactions t2
ON f.who_id = t2.rev_id
where f.whom_id = 2
group by f.who_id, f.who_name
See SQL Fiddle with Demo
Finally I got the answer,
SELECT
p.who_id, p.who_name, COUNT( r1.give_id ) , COUNT( r2.rec_id )
FROM
friends p
LEFT JOIN Transaction r1 ON p.who_id = r1.give_id
LEFT JOIN Transaction r2 on p.who_id = r2.rec_id
WHERE
p.whom_id = 1
GROUP BY p.who_id