Hi I am trying to change some code so that users with certain group id do not show in search results.
at the moment the code is
$query = 'SELECT distinct b.'.$db->nameQuote('id')
.' FROM '.$db->nameQuote('#__users').' b';
I am trying to add something like the following but cannot get it to work.
select * from '.$db->quoteName('#__users').' where id not in (select user_id from #__user_usergroup_map where group_id = 8)
Any help would be appreciated.
Thanks.
This how you can try
select * from users u
where
not exists
(
select 1
from user_group ug
where
u.id = ug.iduser
AND ug.group_id = 8
)
You need change the table name and field name in the above query as your need.
DEMO
There are three ways of doing that.
Method 1: Join
Join usergroup_map table and then, select all rows that have different group_id that way:
SELECT <comma separated fields> from USERS u
LEFT JOIN USERGROUPS ug ON u.user_id = ug.user_id
WHERE ug.group_id != :group_id
GROUP BY u.user_id
And then -> bind any number to :group_id.
Please keep in mind that above statement will return users that are assigned to :group_id only if they are in another groups as well. (one to many relation).
Method 2: Subselect
Already suggested by other users.
Method 3: Join & Subselect
The 3rd, and the last option is to use sub-query within join statement, which tends to be the fastest solution in terms of optimalization. Of course, query times may be different depending on the engine you are working with, but it's worth giving a try.
SELECT <comma separated fields>
FROM USERS u
INNER JOIN (
SELECT g.user_id
FROM USERGROUPS g
WHERE g.group_id != :group_id
) ug ON ug.user_id = u.user_id
--
In this answer, I assume that you have properly configured database with foreign keys.
Related
I have two tables in database, named users(store user details) and posts(store post details). Now i want to get data from both tables. Like user_image from users and post description from post.
I am using this query
SELECT * FROM `users`AS u,`posts` WHERE u.user_id IN (SELECT user_id FROM `posts`)
But it returns duplicate data. I have 2 users and 3 posts but it returns 6 posts.
Try something like:
Select a.user_image, b.post_description from users as a join posts as b on a.user_id = b.user_id
Do an inner join & you shall get the desired result
In the above query a & b are alias for the two different tables. I you do not want to use alias you can also write it as users.user_image in your select statement.
Write the fields you want from both the tables in your select statements.
The below image will help you understand the inner join
Inner Join Circle for understanding
Use group by as below:
SELECT * FROM `users`AS u,`posts` WHERE u.user_id IN (SELECT user_id FROM `posts`) group by u.user_id
What about
Select * FROM user u right join posts p on u.id = p.user_id
?
if you want to get data from both tables you need to use joins.and you make sure the two tables are interlinked by primary keys
so use this can help
select user_image,post_description from users join posts on users.user_id=posts.user_id;
I currently have two tables, "tc_services" and "tc_users" which both have a "USER_ID" field and "BILLING_ID" field. I need to query these together, finding any results where...
A) "tc_services" does not have a "BILLING_ID"
B) "tc_users" does not contain a "USER_ID" that matches that of the coorelating "tc_services"
I am trying to put together a JOIN query statement such as the following but not able to figure it out so far. Any help would be appreciated!
SELECT *
FROM tc_services AS services
JOIN tc_users AS users
WHERE services.USER_ID NOT IN users.USER_ID AND services.BILLING_ID = '';
Something like:
SELECT SERVICE_ID, COUNT(users.USER_ID)
FROM tc_services AS services
LEFT JOIN tc_users AS users ON services.USER_ID = users.USER_ID
WHERE services.BILLING_ID = ''
GROUP BY services.SERVICE_ID HAVING COUNT(users.USER_ID) = 0
Second Edit after seeing your comment:
Just do
SELECT
*
FROM tc_services
WHERE tc_services.billing_id IS NULL AND
tc_services.user_id NOT IN (SELECT user_id FROM tc_users)
No joins needed
Edit:
After rereading your question, you might want an 'LEFT JOIN'
see this picture: http://i.stack.imgur.com/66zgg.png
So your query(s) would look something like
SELECT
*
FROM tc_users u
LEFT JOIN tc_services s ON a.user_id = s.user_id
WHERE s.billing_id IS NULL
which would give you the list of users that don't have a billing ID.
and then similar for the second question.
Original Answer:
Sounds like you might want to use a 'Union' rather than a 'Join'
Check out this related answer: What is the difference between JOIN and UNION?
I have the userids of people who have joined a group in one table but not their names thatlie in another table. So I think I need to do a join. I'm starting with groupid that describes the grouop.
Table 1, groupmem has groupid and userid for the members.
Table 2, users has userid and username
The users table has every user. The groupmem only has some who have joined groups.
SQL statement should be something like following but can't get it to work.
select users.name
FROM users,groupmem
LEFT JOIN users
on groupmem.userid=users.userid
WHERE groupmem.groupid = 22
22 being some value..
Thinking maybe where clause is in wrong place or I am using wrong type of join but or not using on correctly but, in any case, can't get it to work. Thx for any suggestions:
Try:
SELECT u.username
FROM `users` u
LEFT JOIN `groupmem` g
ON u.userid = g.userid
WHERE g.groupid = 22
This should do the trick:
SELECT users.name
FROM groupmem
LEFT JOIN users ON groupmem.userid = users.userid
WHERE groupmem.groupid = 22
Your query seems to be quite right - assuming I guessed your table-structure right.
My goal is that I want to get a list of user names in the database from my "users" table, but omit every user whose ID is also in the "projects_users" table where project_id = 1.
In another words, if these are the tables:
table: users
user_id user_name
1 dave
2 matt
3 james
table: projects_users
user_id project_id
1 2
2 2
3 1
This query would return "dave" and "matt" (since "james" is in the users table, but is also associated with project #1, thus he is omitted).
I understand that I should probably be using some form of join, but my current query is not doing it:
SELECT user_name
FROM users
JOIN projects_users ON (
users.user_id != (projects_users.user_id WHERE projects_users.user_id == 1)
)
This result does not work at all, and earlier experiments kept returning multiple copies of every name. Does anyone know of a way to do this without having to turn to a more manual PHP solution?
Final answer, worked perfectly. Maybe it isn't as optimised as some of the other solutions, but it's the only one that gave me valid results every time. For some reason, the other solutions sometimes popped out an unexpected name, or no name at all when they should have. Regardless, this sure beats doing it the long way with PHP.
SELECT user_id, user_name FROM users WHERE user_id NOT IN (SELECT user_id FROM projects_users WHERE project_id = 1)
Thanks everyone for your contributions. I appreciate all of your help and input.
Original answer
Utilize the power of a LEFT JOIN.
SELECT u.*
FROM users u
LEFT JOIN project_users pu ON u.user_id = pu.user_id
WHERE pu.project_id IS NULL OR pu.project_id <> 1;
Unlike JOIN (which is a shortcut for INNER JOIN), LEFT JOIN selects all rows from main table and their matching rows from joined table, BUT if the matching row is not found, a fake one is returned with all fields set to NULL.
Edit
When I re-read the question, it appeared to me that I got it wrong. If you want to filter out only users that are associated with a certain project, then this is a query to use.
SELECT DISTINCT u.user_id, u.user_name
FROM project_users pu
LEFT JOIN users u ON u.user_id = pu.user_id
WHERE pu.project_id <> 1;
try this:
SELECT DISTINCT
users.user_id,
user_name
FROM
projects_users
RIGHT JOIN
users
ON
users.user_id = projects_users.user_id
WHERE
projects_users.project_id <> 1
OR
projects_users.project_id IS NULL
Try the following:
select u.*
from users u
where exists (select null
from projects_users pu1
where u.user_id = pu1.user_id)
and not exists (select null
from projects_users pu2
where u.user_id = pu2.user_id and pu2.project_id = 1)
Alternatively:
select u.*
from users u
join projects_users pu on u.user_id = pu.user_id
group by u.user_id
having max(case when pu.project_id = 1 then 1 else 0 end) = 0
Currently I am working on a Wordpress site, and I would like it to be possible to search for users on their first and last name on a part of my site.
Wordpress makes use of a meta table to store any 'extra' data for a user. And the first and last name are some of those meta fields.
Now I am trying to create a query which gets me a result which returns me a user matching the first and last name, the only problem is that there is a meta row for last name and another one for first-name, they both do have a reference to the same user_id. Only I don't know how I can create the query correctly.
When I have this query
SELECT U.id FROM wp_users AS U, wp_usermeta as US
WHERE U.id=US.user_id
AND (US.meta_key='first_name' AND US.meta_value='MyFirstName')
It does return the user I am looking for, however when I try this
SELECT U.id FROM wp_users AS U, wp_usermeta as US
WHERE U.id=US.user_id
AND (US.meta_key='first_name' AND US.meta_value='MyFirstName')
AND (US.meta_key='last_name' AND US.meta_value='Dijkstra')
I get no results at all, could someone help me?
In case someone is interested in the database structure, here ( http://cl.ly/6rGx ) is the users table and here ( http://cl.ly/6rts ) is the users_meta table.
Thanks in advance
You can't join one row to two other rows of another table at the same time, so you need to join the other table twice, once for first name and once for last name. Like this:
SELECT U.id
FROM wp_users AS U
inner join wp_usermeta as UMF on U.id = UMF.user_id
inner join wp_usermeta as UML on U.id = UML.user_id
WHERE UMF.meta_key = 'first_name'
AND UMF.meta_value = 'MyFirstName'
AND UML.meta_key = 'last_name'
AND UML.meta_value = 'Dijkstra'
You need to join twice, with different conditions for each. The conditions can be in the WHERE clause as RedFilter suggested, but I prefer compound conditionals in the JOIN clause for readability.
SELECT U.id
FROM wp_users U
join wp_usermeta f on U.id = f.id
and f.meta_key='first_name'
and f.meta_value='MyFirstName'
join wp_usermeta l on U.id = l.id
and l.meta_key='last_name'
and l.meta_value='Dijkstra'
A slightly different version with the keys in the join and the requested values in the where clause:
SELECT U.id
FROM wp_users U
join wp_usermeta f on U.id = f.id and f.meta_key='first_name'
join wp_usermeta l on U.id = l.id and l.meta_key='last_name'
where f.meta_value='MyFirstName' and l.meta_value='Dijkstra'
Consider the logic by re-writing the order of the ANDs (no, parens don't make a difference).
US.meta_key='first_name' AND US.meta_key='last_name' AND
US.meta_value='MyFirstName' AND US.meta_value='Dijkstra'
See the problem? This condition will never be true, because neither US.meta_key nor US.meta_value will never be two values. You need to use an OR, not and AND.
EDIT
A query like this would give you the desired results:
SELECT U.id FROM wp_users AS U, wp_usermeta as US
WHERE U.id=US.user_id AND (
(US.meta_key='first_name' AND US.meta_value='MyFirstName')
OR (US.meta_key='last_name' AND US.meta_value='Dijkstra'))