Is it possible to JOIN in a query and use a NOT IN() clause?
What I have is
SELECT DISTINCT loc.*,
a.firstname,
a.lastname,
a.profileimg,
(((acos(sin((37.2790669*pi()/180)) * sin((`latitude`*pi()/180))+cos((37.2790669*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((-121.874722 - `longitude`)*pi()/180))))*180/pi())*60*1.1515) AS `distance` FROM memb_geo_locations loc
JOIN memb_baseInfo a ON a.mID = loc.mID
JOIN memb_friends c ON (c.mID = loc.mID OR c.friendID = loc.mID) AND (c.mID = 21 OR c.friendID = 21)
WHERE loc.primaryAddress = '1'
AND loc.mID NOT IN(21)
HAVING `distance` < 25 ORDER BY `distance` ASC LIMIT 0, 25
I need this line
JOIN memb_friends c ON (c.mID = loc.mID OR c.friendID = loc.mID) AND (c.mID = 21 OR c.friendID = 21)
to act as a NOT IN() cause I am trying to exclude people from the results that are "friends"
on the memb_friends table both column mID and friendID are in a sense the same number. Dependant upon who initiated the request for a friendship. So lets say my ID is 21 I can either be the friendID or the mID on that table and someone else's ID is the counterpart. I have 10 friends on my list lets say, and 1000 people in my database. So the conclusion should be I have 990 results to work with after the query is done, but Im stuck on this one, either how to JOIN the table in for use with the query and then how to exclude from there.
How about doing an outer join and only selecting those rows where c.mID is null?
Related
Overview
I have two tables - tmc_users and tmc_user_usergroup_map.
In tmc_users, there is a list of user_ids and in tmc_usergroup_map each user_id can be associated with multiple group_ids.
I am trying to find all the user_ids who have a group_id of 12 but do not have a group_id of 17.
Each user can be a member of both.
Current query
This is the query to get all the users associated with the group_id 12, which returns a total number of 1439 rows:
SELECT `id`, LTRIM(RTRIM(`name`)), COUNT(`id`) AS `total`
FROM `tmc_users` u
LEFT JOIN `tmc_user_usergroup_map` g
ON u.`id` = g.`user_id`
WHERE g.`group_id` = 12
ORDER BY LTRIM(RTRIM(`name`)) ASC
New query
This is what I've tried in order to filter out users who also are in the group_id 17:
SELECT `id`, LTRIM(RTRIM(`name`)), COUNT(`id`) AS `total`
FROM `tmc_users` u
LEFT JOIN `tmc_user_usergroup_map` g
ON u.`id` = g.`user_id`
WHERE g.`group_id` != 17
AND g.`group_id` = 12
ORDER BY LTRIM(RTRIM(`name`)) ASC
However, this returns the same number of rows - 1439 - whereas the actual number of users this should have is 1353.
How can I make this work in one single query?
You can use NOT EXISTS:
SELECT `id`, LTRIM(RTRIM(`name`)), COUNT(`id`) AS `total`
FROM `tmc_users` u
LEFT JOIN `tmc_user_usergroup_map` g
ON u.`id` = g.`user_id`
WHERE g.`group_id` = 12 AND
NOT EXISTS (SELECT 1
FROM `tmc_user_usergroup_map` AS t
WHERE t.`user_id` = u.`id` AND t.`group_id` = 17)
ORDER BY LTRIM(RTRIM(`name`)) ASC
I need help about generating query for multiple column.
part of my tbl_advert_specific_fields_values table look like:
id advert_id field_name field_value
1 654 t1_sqft 50
2 655 t1_yearbuilt 1999
3 1521 t2_doorcount 5
4 656 t1_yearbuilt 2001
5 656 t1_sqft 29
6 654 t1_yearbuilt 2004
SELECT p.*, p.id AS id, p.title AS title, usr.id as advert_user_id,
p.street_num, p.street,c.icon AS cat_icon,c.title AS cat_title,c.title AS cat_title,
p.description as description,
countries.title as country_name,
states.title as state_name,
date_FORMAT(p.created, '%Y-%m-%d') as fcreated
FROM tbl AS p
LEFT JOIN tbl_advertmid AS pm ON pm.advert_id = p.id
INNER JOIN tbl_usermid AS am ON am.advert_id = p.id
LEFT JOIN tbl_users AS usr ON usr.id = am.user_id
INNER JOIN tbl_categories AS c ON c.id = pm.cat_id
INNER JOIN tbl_advert_specific_fields_values AS asfv ON asfv.advert_id = p.id
LEFT JOIN tbl_countries AS countries ON countries.id = p.country
LEFT JOIN tbl_states AS states ON states.id = p.locstate
WHERE p.published = 1 AND p.approved = 1 AND c.published = 1
AND (asfv.field_name = 't1_yearbuilt'
AND CONVERT(asfv.field_value,SIGNED) <= 2004 )
AND (asfv.field_name = 't1_sqft'
AND CONVERT(asfv.field_value,SIGNED) <= 50)
AND p.price <= 10174945 AND (p.advert_type_id = 1)
AND (c.id = 43 OR c.parent = 43)
GROUP BY p.id
ORDER BY p.price DESC
ok, the problem is in this asfv query part that are generated dynamically. It belong to objects which represent adverts by its specific fields. asfv is actually advert_specific_fields_values table (table name say all about it).
Without part:
AND (asfv.field_name = 't1_yearbuilt'
AND CONVERT(asfv.field_value,SIGNED) <= 2004 )
AND (asfv.field_name = 't1_sqft'
AND CONVERT(asfv.field_value,SIGNED) <= 50)
query return all adverts that belong on advert_type_id and price of them are less than 10.174.945,00 €.
All what I need is query update that return only adverts, for example t1_yearbuilt less than 2005 and t1_sqft less than 51 (advert_id => 654,656).
I also need query for values between for example t1_sqft >=30 AND t1_sqft <=50 (advert_id => 654).
Can anybody know how, update this query?
TNX
Each modx_site_content record may have several records in modx_site_tmplvar_contentvalues.
I need to retrieve both modx_site_tmplvar_contentvalues.value where the tvv.tmplvarid = 3 AND the tvv.tmplvarid = 1. where tvv.tmplvarid is a future date, I need to return the tvv.value of tvv.tmplvarid 3 which is a comma separated list of tags.
This query does not return the values I need & I'm not sure how to get just what I want.
SELECT sc.id, sc.pagetitle, tvv.value, tvv.tmplvarid, tvv.id, tvv.value
FROM modx_site_content sc
left join modx_site_tmplvar_contentvalues tvv on tvv.contentid = sc.id
where published = '1'
and (tvv.tmplvarid = '3' and tvv.value >= curdate())
order by sc.id;
basically in the end I need to return only the list of tags (tvv.tmplvarid = 3) where the other associated record (tvv.tmplvarid = 1) is a date in the future.
Any thoughts, can this be done with grouping instead? I don't actually need anything from the modx_site_content table.
So you need to return the tags both rows in the modx_site_tmplvar_contentvalues table that has tmplvarid of 1 and 3 both related to the same modx_site_content, but only when the tmplvarid 3 row has a datetime field in the future?
I would do two separate joins to the modx_site_tmplvar_contentvalues tabe:
SELECT tOne.value, tThree.value
FROM modx_site_tmplvar_contentvalues tOne
INNER JOIN modx_site_content c ON tOne.contentid = c.id
INNER JOIN modx_site_tmplvar_contentvalues tThree ON tThree.contentid = c.id
WHERE c.published = 1
AND tOne.tmplvarid = 1
AND tThree.tmplvarid = 3 AND tThree.date > NOW()
SQL Fiddle: http://sqlfiddle.com/#!2/a4031/2
I figured it out. Amazing what you can do if you just read the docs ;)
select tv.contentid, tv.value as eventdate, sc.id, sc.pagetitle, tvv.value from
(
select * from modx_site_tmplvar_contentvalues cv
where cv.tmplvarid = 3
and cv.value >= curdate()
) as tv
left join modx_site_content sc on sc.id = tv.contentid
left join modx_site_tmplvar_contentvalues tvv on tvv.contentid = sc.id
where (tvv.tmplvarid = 1)
order by value asc
Hi hope someone can advise
I have a sql query that went it runs it repeats the same result by the number of users (entries) made
for example:
post_id
20
20
19
19
18
18
Here is the query it takes no arguments, could someone explain why this is happening please?
Thanks
SELECT DISTINCT post_look.post_id, post_look.look_id, post_look.date_posted, looks.title, looks.item_id, user.user_id, user.first_name, user.last_name, user_account.profile_image, user_account.account_status, add_profile_images.image_name
FROM post_look
JOIN looks ON looks.look_id = post_look.look_id
JOIN add_look_item ON add_look_item.look_id = looks.look_id
JOIN item ON item.item_id = add_look_item.item_id
JOIN add_images ON add_images.item_id = item.item_id
JOIN user_item ON user_item.item_id = item.item_id
JOIN user_account ON user_account.account_id = user_item.account_id
JOIN user ON user.user_id = user_account.user_id
JOIN users_profile_images ON users_profile_images.account_id = user_account.account_id
JOIN add_profile_images ON add_profile_images.image_id = users_profile_images.image_id
ORDER BY post_look.post_id DESC
LIMIT 0 , 30
SELECT DISTINCT c1, c2, c3
means that {c1, c2, c3} will be distinct.
You should consider adding GROUP BY post_look.post_id to your query.
See the difference here:
DISTINCT
GROUP BY
Would you please try it?
SELECT post_look.post_id, post_look.look_id, post_look.date_posted, looks.title, looks.item_id, user.user_id, user.first_name, user.last_name, user_account.profile_image, user_account.account_status, add_profile_images.image_name
FROM post_look
JOIN looks ON looks.look_id = post_look.look_id
JOIN add_look_item ON add_look_item.look_id = looks.look_id
JOIN item ON item.item_id = add_look_item.item_id
JOIN add_images ON add_images.item_id = item.item_id
JOIN user_item ON user_item.item_id = item.item_id
JOIN user_account ON user_account.account_id = user_item.account_id
JOIN user ON user.user_id = user_account.user_id
JOIN users_profile_images ON users_profile_images.account_id = user_account.account_id
JOIN add_profile_images ON add_profile_images.image_id = users_profile_images.image_id
GROUP BY post_look.post_id
ORDER BY post_look.post_id DESC
LIMIT 0 , 30
I've got a query that is running awfully slow:
SELECT *
FROM games
WHERE games.platform =13
AND games.id NOT
IN (SELECT game_id
FROM collections
WHERE collections.user_id =1)
I attempted to rewrite it as a left join but it's returned 0 results:
SELECT *
FROM games
LEFT JOIN collections ON collections.game_id = games.id
WHERE collections.game_id IS NULL AND collections.user_id = 1 AND games.platform = 13
ORDER BY games.name ASC
Could someone point out my error here?
SELECT games.*
FROM games
LEFT JOIN collections
ON collections.user_id = 1
AND collections.game_id = games.id
WHERE games.platform = 13
AND collections.game_id IS NULL
ORDER BY games.name ASC
you need indexes on
(games.id,platform,name)
(collections.user_id,collections.game_id)