Users Table
id
---
1
2
3
4
5
6
Interests Table
user_id interest_id
-------- -----------
1 34
2 34
3 34
2 45
1 45
3 46
4 47
5 34
6 78
Expected Result (say I am the user with the id of 1)
user_id mutual_interest_count
-------- ---------------------
2 2
3 1
4 0
5 1
6 0
How can I build the query finding the mutual interests?
We can use a self join with aggregation approach here:
SELECT u.id, COALESCE(t.cnt, 0) AS mutual_interest_count
FROM Users u
LEFT JOIN
(
SELECT t2.user_id, COUNT(*) AS cnt
FROM Interests t1
INNER JOIN Interests t2 ON t2.interest_id = t1.interest_id
WHERE t1.user_id = 1 AND t2.user_id <> 1
GROUP BY t2.user_id
) t
ON t.user_id = u.id
WHERE u.id <> 1;
Here is a working demo on MySQL 8.
SELECT Users.id, COUNT(t2.user_id) mutual_interest_count
FROM Users
LEFT JOIN Interests t1 ON t1.user_id = Users.id
LEFT JOIN Interests t2 ON t1.interest_id = t2.interest_id
AND t2.user_id = 1
WHERE Users.id <> 1
GROUP BY Users.id
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=ea982860620f489855edca217c0169ae
Related
I have 3 tables in which all 3 tables are joined to get the result.
Below is the table,
//tbl_order
order_id order_no_first order_no order_no_last order_date
---------------------------------------------------------------------
1 C 1000 a 2017-05-16
2 C 1001 a 2017-05-16
3 C 1001 b 2017-05-16
4 A 1002 a 2017-05-16
5 A 1002 b 2017-05-16
//tbl_assign
assign_id order_id order_no_first central_status central_assign_unit
----------------------------------------------------------------------------
1 1 C 1 1
2 2 C 1 1
3 3 C 1 1
4 4 A 1 1
//tbl_unit_status
status_id assign_id status_status
---------------------------------------
1 1 Cutter
2 1 Stitch
3 1 Delivery
4 2 Cutter
5 2 Stitch
6 3 Cutter
7 4 Cutter
I want the result as below,
//Required output
order_id assign_id order_no_first order_no order_no_last status_status
---------------------------------------------------------------------------
2 2 C 1001 a Stitch
3 3 C 1001 b Cutter
4 4 A 1002 a Cutter
5 A 1002 b
from the table tbl_unit_status the status below status_status field, if it is Despatch then do not display that result.
I have tried to get the above result. But no success below is my code.
`SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id AND o.order_no_first = a.order_no_first
LEFT JOIN (
SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u GROUP BY u.assign_id) uu
ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2 on u2.status_id = uu.maxid
WHERE a.central_status = 1 AND a.central_assign_unit = 1
OR (u2.status_status != "Delivery" AND u2.status_status != "Despatch")
GROUP BY o.order_id
From the above code, the result is
//wrong output
order_id assign_id order_no_first order_no order_no_last status_status
---------------------------------------------------------------------------
1 1 C 1000 a Delivery
2 2 C 1001 a Stitch
3 3 C 1001 b Cutter
4 4 A 1002 a Cutter
5 A 1002 b
Is there any way to get the Required output as soon in the first output. I have tried and am stuck in here.
Thank you.
Use parenthesis correctly arround AND OR clauses and I recommend using NOT LIKE instead of != when dealing with strings.
SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id AND o.order_no_first = a.order_no_first
LEFT JOIN (
SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u GROUP BY u.assign_id) uu
ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2 on u2.status_id = uu.maxid
WHERE a.central_status = 1 AND (a.central_assign_unit = 1 OR u2.status_status NOT LIKE 'Delivery' AND u2.status_status NOT LIKE 'Despatch')
GROUP BY o.order_id
Obs: I can't comment due to my reputation, I'm sorry
You should be using AND instead of OR in your where clause. You don't need the parentheses either.
SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id
AND o.order_no_first = a.order_no_first
LEFT JOIN
(SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u
GROUP BY u.assign_id
) uu ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2
on u2.status_id = uu.maxid
WHERE a.central_status = 1
AND a.central_assign_unit = 1
AND (
u2.status_status IS NULL
OR
u2.status_status NOT IN ("Delivery", "Despatch")
)
GROUP BY o.order_id
I have table1 like this:
ID uid jid type val
1 1 1 1 1
2 1 1 1 10
3 1 2 1 100
4 1 3 1 1000
5 1 4 2 2
And joined table2:
ID uid jid stat time
1 1 1 1 100
2 1 1 1 200
3 1 1 4 300
4 1 2 2 400
I try to get SUM of val from table1, group it by uid and type and join table2 by this query:
SELECT a.uid, a.type, SUM(a.val) as t1, SUM(a.val)*COUNT(distinct(a.id))/COUNT(a.id) as t2, MAX(b.time) as max_time
FROM table1 as a
LEFT JOIN table2 as b on b.uid = a.uid and b.jid = a.jid and b.stat = 1
GROUP BY a.uid, a.type
In result I get this values:
uid type t1 t2 max_time
1 1 1122 748.0000 200
1 2 2 2.0000 NULL
But total for type=1 should be: 1111 (not 1122 and not 748)
Please tell me what I'm doing wrong.
You need use DISTINCT with a.uid in select statement. corrected query is below:
SELECT DISTINCT(a.uid), a.type, SUM(a.val) AS t1, SUM(a.val)*COUNT(DISTINCT(a.id))/COUNT(a.id) AS t2, MAX(b.time) AS max_time
FROM table1 AS a
LEFT JOIN table2 AS b ON b.uid = a.uid AND b.jid = a.jid AND b.stat = 1
GROUP BY a.uid, a.type
can you recheck the sql:
SELECT auid, atype, SUM(aval)
, SUM(aval)*COUNT(DISTINCT(aid))/COUNT(aid) AS t2, MAX(btime) AS max_time
FROM
(
SELECT DISTINCT(a.uid) AS auid, a.type AS atype, a.val AS aval, a.id AS aid, b.time AS btime
FROM table1 AS a
LEFT JOIN table2 AS b ON b.uid = a.uid AND b.jid = a.jid AND b.stat = 1
) AS grouptable
GROUP BY auid, atype
Output I got:
auid atype sum(aval) t2 max_time
1 1 1111 1111.0000 200
1 2 2 2.0000 (NULL)
Is the result you are looking for?
i have 2 table with this structure
Products
id title
-----------------
1 sample 1
2 sample 2
3 sample 3
4 sample 4
5 sample 5
6 sample 6
gallery
id typeid name
-------------------------------
1 1 sample for 1
2 1 sample for 1
3 1 sample for 1
4 2 sample for 2
5 2 sample for 2
7 2 sample for 2
8 3 sample for 3
9 3 sample for 3
10 3 sample for 3
11 4 sample for 4
12 4 sample for 4
13 5 sample for 5
14 5 sample for 5
and iwant this for lists of id eg(1,2,3)
id typeid name
---------------------
1 1 sample for 1
1 2 sample for 1
2 4 sample for 2
2 5 sample for 2
3 8 sample for 3
3 9 sample for 3
here is my query
select p.*,g.* from products p inner join gallery g ON p.id=g.typeid where p.id in (3,4,5) group by typeid
here is real structure sqlfiddle link
SELECT p.id, g.typeid, g.id, g.title
FROM products p
INNER JOIN (SELECT * FROM gallery a
WHERE (SELECT COUNT(*) FROM gallery b WHERE b.title = a.title AND b.id >= a.id) <= 2
) g ON p.id = g.typeid
WHERE p.id in (3,4,5)
EDIT:
Try this SQL Fiddle Demo
SELECT p.id, g.typeid, g.id, g.name
FROM products p
INNER JOIN (SELECT * FROM gallery a
WHERE (SELECT COUNT(*) FROM gallery b WHERE b.typeid = a.typeid AND b.id >= a.id) <= 2
) g ON p.id = g.typeid
WHERE p.id in (3,4,5) order by g.id asc
So basically this part
WHERE (SELECT COUNT(*) FROM gallery b WHERE b.title = a.title AND b.id >= a.id) <= 2
is used to replace group by typeid
SELECT p.id,p.title, g.typeid, g.id, g.name
FROM products p
INNER JOIN (SELECT * FROM gallery a
WHERE (SELECT COUNT(*) FROM gallery b WHERE b.typeid = a.typeid AND b.id >= a.id)
please try this
I have two tables like this:
table_1
id user_id item_id item_number
15 1 1 7
16 1 2 12
17 1 3 1
18 1 4 0
19 1 5 11
20 5 1 2
21 5 2 2
22 5 3 5
23 5 4 7
24 5 5 1
table_2
id user_id item_id attribute
41 5 1 1
42 1 1 1
43 7 5 1
44 1 4 1
45 1 4 0
I would like to select user_id, item_id and item_number from table_1 and number of rows from table_2 where table_1.user_id = table_2.user_id and table_1.item_id = table_2.item_id.
I have this:
SELECT item_id, item_number, COUNT(attribute) AS number
FROM table_1
LEFT OUTER JOIN table_2 ON table_1.user_id = table_2.user_id
WHERE table_1.user_id='1'
Can you help me?
Expected result:
user_id item_id item_number number
1 1 7 1
1 2 12 0
1 3 1 0
1 4 0 2
1 5 11 0
Try this:
SELECT t1.user_id, t1.item_id, t1.item_number, COUNT(attribute) AS number
FROM table_1 t1
LEFT OUTER JOIN table_2 t2 ON t1.user_id = t2.user_id AND t1.item_id = t2.item_id
WHERE t1.user_id = '1'
GROUP BY t1.user_id, t1.item_id;
you have to use alias as same column names confuses the server to identify which column have to fetch..so you can use this..
SELECT t1.user_id,t1.item_id, t1.item_number, COUNT(attribute) AS number
FROM table_1 t1
LEFT OUTER JOIN table_2 t2 ON t1.user_id = t2.user_id
WHERE t1.user_id='1' GROUP BY t1.user_id, t1.item_id;
Since you don't really need any column values from table_2, I'd go with a sub-query to get the count:
select user_id, item_id, item_number,
(select count(*) from table_2
where table_1.user_id = table_2.user_id
and table_1.item_id = table_2.item_id)
from table_1
WHERE table_1.user_id='1'
I have join with a multiple tables. You can find the tables and MySQL query in this demo.
These are the tables:
users
id name
1 abc
2 xyz
3 pqr
friend
user_id friend_id
1 2
1 3
2 3
collection
id user_id friend_id amount
1 1 2 100
2 2 1 -100
3 2 3 200
4 3 2 -200
5 1 3 300
6 3 1 -300
bill
id use_id(bill_creator)
1 1
2 2
3 2
bill_person
id bill_id user_id
1 1 1
2 1 2
3 1 3
4 2 2
5 2 3
6 3 2
6 3 1
So far I have made this query:
SELECT mf.id
, mf.name
, c.amount AS amount,count(bp.user_id) AS no_common_bills
FROM (
SELECT fr.user_id AS user_id
, fr.friend_id AS friend_id
FROM friend fr
JOIN users fru
ON fru.id = fr.user_id
WHERE fru.id IN (1)
UNION
SELECT fl.friend_id AS user_id
, fl.user_id AS friend_id
FROM friend fl
JOIN users flf
ON flf.id = fl.friend_id
WHERE flf.id IN (1)
) f
JOIN users mf
ON mf.id = f.friend_id
LEFT
JOIN collection c
ON c.friend_id = mf.id
AND c.user_id = f.user_id
LEFT JOIN bill_person bp
ON bp.user_id=f.user_id AND c.friend_id = mf.id
GROUP BY mf.id
ORDER BY mf.id
and my output of this query is
id NAME AMOUNT NO_COMMON_BILLS
2 XYZ 100 2
3 PQR 300 2
but I want this result:
id NAME AMOUNT NO_COMMON_BILLS
2 XYZ 100 2
3 PQR 300 1
I am getting wrong output at NO_COMMON_BILLS. Other than that, all values are correct.
Third time's a charm...
http://sqlfiddle.com/#!2/338dd/12
SELECT u.name friend
, COUNT(bp2.user_id) no_common_bills
FROM users u
LEFT
JOIN
( SELECT user_id me, friend_id them FROM friend WHERE user_id = 1
UNION
SELECT friend_id,user_id FROM friend WHERE friend_id = 1
) x
ON x.them = u.id
LEFT
JOIN bill_person bp1
ON bp1.user_id = x.them
LEFT
JOIN bill_person bp2
ON bp2.bill_id = bp1.bill_id
AND bp2.user_id = x.me
WHERE u.id <> 1
GROUP
BY friend;
FRIEND NO_COMMON_BILLS
jkl 0
mno 0
pqr 1
xyz 2