Mysql joining derived tables - mysql

This is one where I'm not sure if there is a better approach or not. maybe I just have a syntax error that I'm not seeing. either way here's the issue.
I am trying to get the number of my "friends" (defined by me following them and them following me ,join 1 creating a derived table) that are also following the object I'm looking at in the database. (join 2). this is in a custom function not a stored procedure so I can reuse it in several places. the only pertinant columns are profile_id and follower_profile_id. profile_id is the profile being followed, follower_profile_id is the one doing the following.
here is the query:
set followsThatCorrelate =
(
Select count(id)
from
(
select * from followers as shouldFollow
join
(
(select *
from followers
where followers.profile_id = authUserId
) as followingMe
join
(select *
from followers
where followers.follower_profile_id = authUserId
) as myFollows
on myFollows.profile_id = followingMe.follower_profile_id
) as friends1
on shouldFollow.follower_profile_id = friends1.follower_profile_id
where shouldFollow.profile_id = otherId
)
);
it says my syntax error is after I alias the derived table friends. no matter what I put after that it always throws the exception.

CREATE TABLE followers (
profile_id NVARCHAR(5),
follower_profile_id NVARCHAR(5)
);
INSERT INTO followers
VALUES ('Tom','Dick'),('Dick','Tom'),('Carry', 'Tom'),('Tom','Carry'),('John','Tom');
SET #authUserID = 'Tom';
SELECT followsme.follower_profile_id as followerID
FROM followers followsme
-- Join back to the followers table
INNER JOIN followers ifollow
-- get all of your followers followers
ON followsme.follower_profile_id = ifollow.profile_id
-- filter your followers followers to only you.
AND ifollow.follower_profile_id = #authUserId
-- this restricts the original set to only your followers
WHERE followsme.profile_id = #authUserId

Related

MySQL SELECT query from multiple tables at the same time

I have schema like this in my database:
I want to display all recipes (with specific fields) which specific user (given with unique_id) has added to his favourites which are desscribed in table favourite (2 fields - user id and liked recipe). I have no idea how to to that.
f.e. If user likes 5 recipes, that information is included in the favourite table (his id and recipe he liked id). I want to display fields:
recipe.unique_id,
recipe.title,
recipe.img_tumbnail_link,
recipe.add_date,
recipe.kitchen_type,
recipe.meal_type,
user.name,
user.surname,
COUNT(like.recipe_unique_id_fk) AS like_count
I've tried to do some query with this:
SELECT recipe.`unique_id`, recipe.`title`, recipe.`img_tumbnail_link`, recipe.`add_date`, recipe.`kitchen_type`, recipe.`meal_type`, user.`name`, user.`surname`, COUNT(`like`.`recipe_unique_id_fk`) AS like_count
FROM `recipe`
JOIN `favourite` ON (recipe.`unique_id` = `favourite`.`recipe_unique_id_fk`)
JOIN `like` ON (recipe.`unique_id` = `like`.`recipe_unique_id_fk`)
JOIN `user` ON (recipe.`user_unique_id_fk` = user.`unique_id`)
WHERE favourite.`user_unique_id_fk` = '565096811c0b51.08471830'
ORDER BY recipe.`add_date` DESC
From table like this:
with this query i receive only 1 row instead of 3 I should get for user with id: 565096811c0b51.08471830. Any help? Thank you.
I've added recipes table and result:)
Here is my query result:
Here is all records (no duplicate): http://postimg.org/image/ejjemnozb/
You are using join with like table as well which is having only one row thats why only one row is returned. You can calculate likes with sub-query. I have mentioned correct query below:
SELECT recipe.`unique_id`, recipe.`title`, recipe.`img_tumbnail_link`, recipe.`add_date`, recipe.`kitchen_type`, recipe.`meal_type`, user.`name`, user.`surname`,
(SELECT count(*) from `like` WHERE recipe.`unique_id` = `like`.`recipe_unique_id_fk`) AS like_count
FROM `recipe`
JOIN `favourite` ON (recipe.`unique_id` = `favourite`.`recipe_unique_id_fk`)
JOIN `user` ON (recipe.`user_unique_id_fk` = user.`unique_id`)
WHERE favourite.`user_unique_id_fk` = '565096811c0b51.08471830'
ORDER BY recipe.`add_date` DESC

MySQL Join Query 4 tables

I'm trying to create a query with multiple joins, but it's not working for me.
I have the follow query statement:
SELECT DISTINCT s.per_id
, s.per_key
, s.per_disabled
, p.acc_id
, a.acc_name
, p.approved_acc_id
, p.per_time
FROM acc_permissions p
JOIN svr_permissions s
JOIN acc_general a
JOIN svr_group_permissions g
WHERE a.acc_id = p.acc_id
AND p.per_id = s.per_id
OR a.acc_per_group = g.group_id
AND a.acc_id = p.acc_id
Now if you don't want to examine this query, I understand so I will example my table structure;
First Table (includes users):
acc_general
Second table (includes permissions (linked to users)):
acc_permission
- This table includes rows that are linked to the acc_id in acc_general.
Multiple rows are possible for one unique acc_id in this table.
Third table (includes permissions (liked to groups)):
group_permissions
Now this includes rows that are linked to groups, each group has multiple rows in this table.
Inside acc_general there is a field called; acc_group_id, this is liked with the group_id inside group_permissions
So I need a query that returns all permissions from all players.
But it should not create duplicated permissions for a account.
So if I have an account that has a permission id 1 inside acc_permission and it has permission id 1 inside group_permissions it should ignore it.
It's hard to example, but i hope someone understands what I want.
Regards, Roel
join syntax for your query
SELECT DISTINCT s.per_id AS per_id,
s.per_key AS per_key,
s.per_disabled AS per_disabled,
p.acc_id AS acc_id,
a.acc_name as acc_name,
p.approved_acc_id AS approved_acc_id,
p.per_time AS per_time
from acc_permissions p
join svr_permissions s
ON p.per_id = s.per_id
join acc_general a
ON a.acc_id= p.acc_id
left join svr_group_permissions g
ON a.acc_per_group = g.group_id

Trying to building optimised Query for Group and Subgroup for a user

i am trying to write the Query for three things .My table structure is like that
You can see Schema at http://sqlfiddle.com/#!2/56c2d/1
I am trying to write the query in MYSQL
user:- table
user_id
user_fname
This is User tabke which will save User Information
group:- "group" and "subgroup" is maintain in same table using column "group_parent_group_id"
group_id
group_title
group_parent_group_id(INT)
This is group table which will save Group and Subgroups
user_group: table
user_group_id
user_group_user_id
user_group_group_id
This ill store both User and Group relation using their Id
I am trying to write the Query for three things. Fetching Users Groups, Subgroups
1) Query to fetch list of All Groups for User Register. Query is gelow and is giving error
Query:
select user.id, user.user_fname, group.group_id, group.group_title
from `user`
inner join user_group on user_group.user_group_user_id = user.user_id
inner join group on group.group_id = user_group.user_group_group_id
where user_group.user_group_user_id = 1 and user_group.group_parent_group_id = 0
2) I am Looking the query to fetch all subgroups(For Whom user is already Register) for Group Id 1,2 or 1
3) I am Looking the query to fetch all subgroups(For Whom user is Not Register yet) for Group Id 1,2 or 1. Ideal is for giving him randomly suggest a subgroup to add
Please Help. I am a newbie in DB :(
Your query is probably failing as you have a table called group, which is a reserved word. You can use back tics to delimit the name to get away with this (as follows) but it would be a better idea to change the table name.
SELECT user.id, user.user_fname, `group`.group_id, `group`.group_title
FROM `user`
INNER JOIN user_group ON user_group.user_group_user_id = user.user_id
INNER JOIN `group` ON `group`.group_id = user_group.user_group_group_id
WHERE user_group.user_group_user_id = 1
AND user_group.group_parent_group_id = 0
EDIT updated for queries I think the OP requires.
First query will get a list of all the groups (ones that have no parent group id) that a user (in this case id 28) is a member of
SELECT y2m_user.user_id, y2m_user.user_first_name, y2m_group.group_id, y2m_group.group_title
FROM y2m_user
INNER JOIN y2m_user_group ON y2m_user_group.user_group_user_id = y2m_user.user_id
INNER JOIN y2m_group ON y2m_group.group_id = y2m_user_group.user_group_group_id
WHERE y2m_user.user_id = 28
AND y2m_group.group_parent_group_id = 0
This query will get a list of all the sub groups (ones where the parent group id is greater than 0) that a user (in this case id 28) is a member of
SELECT y2m_user.user_id, y2m_user.user_first_name, y2m_group.group_id, y2m_group.group_title
FROM y2m_user
INNER JOIN y2m_user_group ON y2m_user_group.user_group_user_id = y2m_user.user_id
INNER JOIN y2m_group ON y2m_group.group_id = y2m_user_group.user_group_group_id
WHERE y2m_user.user_id = 28
AND y2m_group.group_parent_group_id > 0
This query will get a list of all the sub groups (ones where the parent group id is greater than 0) that a user (in this case id 28) is NOT a member of
SELECT y2m_user.user_id, y2m_user.user_first_name, y2m_group.group_id, y2m_group.group_title
FROM y2m_user
CROSS JOIN y2m_group
LEFT OUTER JOIN y2m_user_group ON y2m_user_group.user_group_user_id = y2m_user.user_id AND y2m_group.group_id = y2m_user_group.user_group_group_id
WHERE y2m_user.user_id = 28
AND y2m_group.group_parent_group_id > 0
AND y2m_user_group.user_group_id IS NULL
Please excuse any typos as not tested (with your test data there are no sub groups).

MySQL - How to count number of rows from primary query, ignore subquery rows?

I use the following MySQL to return a list of posts and their corresponding comments.
SELECT *
FROM forum_qa
JOIN user_profiles
ON user_id = forum_qa_author_id
LEFT JOIN (SELECT forum_cm_id,
forum_cm_author_id,
forum_qa_id_fk,
forum_cm_text,
FROM forum_cm
JOIN user_profiles
ON user_id = forum_cm_author_id) AS c
ON forum_qa_id = c.forum_qa_id_fk
WHERE forum_qa_parent_id = $forum_qa_id
If I run
$data['num_answers'] = $query->num_rows();
This allows me to get the number of returned rows and pass the array to my controller and view.
But this is returning all rows (posts + comments). So if 1 post has 10 comments, it returns 10.
How could I have this query count only the number of posts (ie, returning 1) not including the subquery?
Each post has a unique id saved in forum_qa.forum_qa_id
Each comment has a unique id saved in forum_cm.forum_cm_id.
Thanks for helping -- will post more code if needed.
Not the fastest, but you are not restricted in using GROUP BY:
SELECT *,
(SELECT COUNT(*) FROM forum_qa WHERE forum_qa_parent_id = $forum_qa_id) Cnt
FROM forum_qa
JOIN user_profiles
ON user_id = forum_qa_author_id
LEFT JOIN (SELECT forum_cm_id,
forum_cm_author_id,
forum_qa_id_fk,
forum_cm_text,
FROM forum_cm
JOIN user_profiles
ON user_id = forum_cm_author_id) AS c
ON forum_qa_id = c.forum_qa_id_fk
WHERE forum_qa_parent_id = $forum_qa_id
You can run another query or add one more column (with an independent subquery) in the result set:
SELECT *
, ( SELECT COUNT(*)
FROM forum_qa
WHERE forum_qa_parent_id = $forum_qa_id
) AS cntPosts
FROM forum_qa
JOIN user_profiles
ON user_id = forum_qa_author_id
LEFT JOIN (SELECT forum_cm_id,
forum_cm_author_id,
forum_qa_id_fk,
forum_cm_text,
FROM forum_cm
JOIN user_profiles
ON user_id = forum_cm_author_id) AS c
ON forum_qa_id = c.forum_qa_id_fk
WHERE forum_qa_parent_id = $forum_qa_id
COUNT(DISTINCT forum_qa.forum_qa_id)
COUNT(DISTINCT col_name) counts the distinct post ids. This should equal the number of posts.

Mysql: Get all results that has all this relations

I have two tables:
objects object_features
------------- -------------------
id id
name object_id
term_id
What I want to achieve is, giving a list of features, get all objects that has all of them.
I'm trying this:
SELECT objects.*
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('1','3','4','10')
This is the php code I'm using:
$feature_list = array(1,3,4,10);
$sql = 'SELECT objects.*
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('.implode(',', $feature_list).')';
This is near to what I need, but differing that it returns me any object that has any of the features given, instead of ALL the features
one option is to group by the data you want returned from object and add a having clause that counts object.id and tests to see if it is the same as the length of the array.
SELECT objects.id, objects.name
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('1','3','4','10')
group by objects.id,objects.name
having count(objects.id) = 4
Cant swear to the syntax on that as I've been writing tsql recently and don't have an instance of mysql to test on.
try
'WHERE term_id = '.impode(' AND termid = ', $features_ids).')'
This will result in:
WHERE termid = 1 AND termid = 3 AND termid = 5
Actually you need a GROUP BY to group by each object and using a HAVING clause to allow only rows that have all the termids
SELECT objects.*
FROM `object_features` LEFT JOIN `objects` ON ( objects.id=object_features.object_id)
WHERE term_id IN ('1','3','4','10')
GROUP BY objects.id, objects.name
HAVING count(term_id) = 4
The SQL way of doing it would be:
SELECT objects.*
FROM objects
WHERE null not in
(
select of.object_id
from features f
left join object_features of on (f.id = of.id)
)
Assuming you have a features table with all the features.
If you need to list only certain features, you can do (check out the where condition on the subquery):
SELECT objects.*
FROM objects
WHERE null not in
(
select of.object_id
from features f
left join object_features of on (f.id = of.id)
where f.id in (1,2,3,4,5)
)