Convert inner select query to join in MySQL - mysql

I want to convert my SQL query to Join.
I have two tables.
table: MATCH
ID
Match_Id
User_Id
1
2
1
2
3
1
table: BLOCK
ID
Block_Id
User_Id
1
2
1
Now from the above tables, I want to get the list of MatchIds which are not blocked.
I solve this problem using nested select queries, But I want to solve this problem using the JOINs.
I prepared the below SQL and it is working.
SELECT M.Match_Id
FROM match M
WHERE M.user_id = '1'
AND M.match_id NOT IN
(SELECT B.block_id
FROM block B
WHERE B.block_id IS NOT NULL);

If you do a left join on the block table and look for null records on the join, that is effectively a NOT EXISTS query
SELECT M.Match_Id
FROM match M
LEFT JOIN Block B ON B.block_id == M.match_id
WHERE M.user_id = '1'
AND B.Id IS NULL
Related question

Related

Mysql SELECT eliminate rows duplicate values in one column (joining 2 tables)

This is a different question because I have joined 2 tables. The solutions for the duplicate question indicated does not work for me.
This is the query:
SELECT a.id, a.userName, IF(o.userId = 1, 'C', IF(i.userId = 1,'I','N')) AS relation
FROM tbl_users AS a
LEFT JOIN tbl_contacts AS o ON a.id = o.contactId
LEFT JOIN tbl_invites AS i on a.id = i.invitedId
ORDER BY relation
This returns the output as follows:
id username relation
1 ray C
2 john I
1 ray N
I need to remove the third row from the select query by checking if possible that id is duplicate. I tried adding distinct(a.id) but it doesn't work. How do I do this?

SQL GROUP_CONCAT with LEFT JOIN to multiple relative rows

I have been stuck on this for hours now, any help would be greatly appreciated
I have two tables 'products' and 'product_subcategorys'
'products' holds only unique ids where as 'product_subcategorys' holds multiple ids relative to the 'products' table
'products'
id brand
1 a
2 b
3 a
'product_subcategorys'
id subcat
1 u
1 i
2 u
3 u
this is the query I have, Group by 'p.id' doesn't appear to work
SELECT GROUP_CONCAT(p.brand)
FROM products p
LEFT JOIN product_subcategorys s ON p.id = s.id
WHERE (
s.subcategory = "u"
OR s.subcategory = "i"
) AS GROUPbrand
So my problem is, i want it to return the list of brands only from the 'product' table I cant use distinct because i need to count the multiples
I want the query to return brand 'a' twice, but this query is returning it 3 times since there are two matching ids in the 'product_subcategorys'
Does this do what you want?
SELECT GROUP_CONCAT(p.brand ORDER BY p.id)
FROM products p
WHERE EXISTS (SELECT 1
FROM product_subcategorys s
WHERE p.id = s.id AND
s.subcategory IN ('u', 'i')
);

How to join conditionally with different tables?

I am using MySQL.
I have three tables named ratings, users and one master table master_entityType.
Depending on the values from entityTable column of the master_entityType table, I have to join with another table. If the values from master_entityType is "Blogs", I have to join with blogs table. If the values from master_entityType is "items", I have to join with items table.
SELECT * FROM ratings AS r
LEFT JOIN users AS u ON u.userID = r.userID
LEFT JOIN master_entityType AS ms ON ms.entityTypeID = r.entityTypeID
CASE ms.entityTable
WHEN 'Blogs' THEN INNER JOIN blogs AS b ON b.blogID = r.entityID
END
WHERE r.entityTypeID = '10' AND r.entityID = '1' AND r.userID = '1'
While using the above query I am getting error, please suggest some step to get that query to work.
Structure of the table are as follows,
In users table,
UserID userName isActive
1 Dinesh 1
2 Kumar 1
In ratings table,
ratingID entityID entityTypeID userID rating
1 1 1 1 5
2 4 2 1 4
In master_entityType table,
entityTypeID entityTable entityTypeName entityTypeDescription active
1 blogs Blogs Null 1
2 items Items Null 1
In Items table,
ItemID name collection active
4 pencil 12 1
5 pen 06 1
In blogs table,
blogID name active
1 socail 1
2 private 1
Your design is strange, so performance is likely to be poor.
UNION ALL two tables together and join with the result. Something like this.
If MySQL has views, then create view that unions Items and Blogs table and use the view in other queries. It makes the queries easier to read, understand and maintain.
Here is SQL Fiddle. I adjusted the WHERE condition in the fiddle, because sample data doesn't have any rows with entityTypeID = 10.
SELECT *
FROM
ratings AS r
LEFT JOIN users AS u ON u.userID = r.userID
LEFT JOIN master_entityType AS ms ON ms.entityTypeID = r.entityTypeID
INNER JOIN
(
SELECT
ItemID AS EntityID
,'Items' AS EntityTypeName
,name
,active
FROM items
UNION ALL
SELECT
BlogID AS EntityID
,'Blogs' AS EntityTypeName
,name
,active
FROM blogs
) AS Entities ON
Entities.EntityTypeName = ms.entityTypeName
AND Entities.EntityID = r.entityID
WHERE r.entityTypeID = '10' AND r.entityID = '1' AND r.userID = '1'

Select rows with Left Outer Join and condition - MySQL

PEOPLE PEOPLE_FAVS
id user_id fav_id
------ ------- ----------
1 1 1
2 1 2
3 1 5
4 2 1
5 2 2
6
I have two tables PEOPLE and PEOPLE_FAVS, I am trying to get all PEOPLE which have not favorited number '5' so it should return
PEOPLE
id
------
2
3
4
5
6
I'm trying with this query:
SELECT `people`.`id`
FROM `people`
LEFT OUTER JOIN `people_favs` ON (`people_favs`.`user_id` = `people`.`id`)
WHERE (`people_favs`.`fav_id` != 5)
GROUP BY `people`.`id`
Here is a SQL Fiddle: http://sqlfiddle.com/#!2/4102b8/3
SELECT p.*
FROM people p
LEFT
JOIN people_favs pf
ON pf.user_id = p.id
AND pf.fav_id = 5
WHERE pf.fav_id IS NULL
http://sqlfiddle.com/#!2/665b6/1
You don't actually need to use an outer join. Outer joins are often used when you want to see ALL rows from one table, regardless of their condition with another. While it would work in this case (as seen by Strawberry's example), you can use the NOT EXISTS operator to check for ids that do not have 5 as a favorite.
As far as I am aware, there is little to no performance difference, but this query is a little shorter. I also feel it is a little more logical, because you aren't really joining information. That's just a personal opinion/thought though.
Try this:
SELECT id
FROM people
WHERE NOT EXISTS(SELECT id FROM people_favs WHERE fav_id = 5 AND user_id = id);
SQLFiddle example using your data.
Did you try to simply do this:
SELECT DISTINCT `people`.`id`
FROM `people`
JOIN `people_favs` ON (`people_favs`.`user_id` = `people`.`id`)
WHERE (`people_favs`.`fav_id` <> 5)
GROUP BY `people`.`id`

Selecting rows from multiple tables. How?

Let's say that we have tree tables.
Products Fields Fields Value
---------------- ------------- --------------
pid catid fid catid fid pid value
-------|-------| -----|------- ------|-----|--------
1 1 1 1 1 1 25%
2 1 2 1 1 2 32.5%
3 2 2 1 45%
2 2 42%
3 1 17.3%
3 2 21%
The normal way is selecting Products in a one query and loop through result set(RS1).
Then we select Fields for catid per each row (RS2).
Then doing the same action with RS2 for selecting `Fields Value'.
Only problem is performance issue that will be reduced due to executing a lot of queries` when there are a lot of rows in each table.
Would you suggest me better solution to execute less queries ?
edit
I want to show each product in a box and show fields for each product with it's proper value. joining tree tables together will returns duplicated values for each FieldValue in Products and not usable in loop.
Guessing what you need, try this:
SELECT f.catid, fv.* FROM Fields f
INNER JOIN Products p
ON f.catid = p.catid
INNER JOIN FieldsValue fv
ON fv.fid = f.fid AND fv.pid = p.pid
SELECT *
FROM Products
NATURAL JOIN Fields
NATURAL JOIN FieldsValue;
use Join Syntax :
SELECT * FROM Products as P
LEFT JOIN FieldsValue as FV ON FV.PID = P.PID
LEFT JOIN Fields as F on F.fid = FV.fid
You can join the tables together using left join:
select *
from Products p
left join Fields f on f.catid = p.catid
left join `fields value` fv on fv.fid = f.fid on fv.pid = p.pid
where p.pid = 1