Select rows from a table not matched in another table - mysql

So I have the following:
A lookup table that has two columns and looks like this for example:
userid moduleid
4 4
I also have a users table that has a primary key userid which the lookup table references. The user table has a few users lets say, and looks like this:
userid
1
2
3
4
In this example, it show that the user with ID 4 has a match with module ID 4. The others are not matched to any moduleid.
I need a query that gets me data from the users table WHERE the moduleid is not 4. In my application, I know the module but I don't know the user. So the query should return the other userids apart from 4, because 4 is already matched with module ID 4.
Is this possible to do?

I think I understand your question correctly. You can use a sub-query to cross-check the data between both tables using the NOT IN() function.
The following will select all userid records from the user_tbl table that do not exist in the lookup_tbl table:
SELECT `userid`
FROM `user_tbl`
WHERE `userid` NOT IN (
SELECT DISTINCT(`userid`) FROM `lookup_tbl` WHERE moduleid = 4
)

There are several ways to do this, one pretty intuitive way (in my opinion) is the use an in predicate to exclude the users with moduleid 4 in the lookup table:
SELECT * FROM Users WHERE UserID NOT IN (SELECT UserID FROM Lookup WHERE ModuleID = 4)
There are other ways, with possibly better performance (using a correlated not exists query or a join for instance).

One other option is to use a LEFT JOIN so that you can get the values from both tables, even when there is not a match. Then, pick the rows where there is no userid value from the lookup table.
SELECT u.userid
FROM usersTable u
LEFT JOIN lookupTable lt ON u.userid = lt.userid
WHERE lt.userid IS NULL

Are you looking for a query like this?
select userid from yourtablename where moduleid<>4

Related

MYSQL Join - Using join to get field through 4 tables

I have 4 tables and I wish to use a mysql inner join to the users name (table 1) and type of fav(table 4). Inorder to do this, I need to use user_id to get get corresponding fav_id on table 2, then use the fav_id to get type_of_fav_id on table 3, and finally use type_of_fav_id on table 3 to get type_of_fav on table 4. I will appreciate any help.
Table 1
Users
----------
user_id
first_name
last_name
Table 2
user_favorite
--------
user_fav_id
user_id
fav_id
Table 3
favorites
--------
fav_id
type_of_fav_id
Table 4
types_of_fav
--------
type_of_fav_id
type_of_fav
It's pretty straightforward, actually. Just join each of the four tables, linking the primary key of each to its foreign key counterpart in the following table. Then you can reference the fields that you want in your SELECT clause.
SELECT u.first_name, u.last_name, tof.type_of_fav
FROM users u
JOIN user_favorite uf ON u.user_id = uf.user_id
JOIN favorites f ON uf.fav_id = f.fav_id
JOIN types_of_fav tof on f.type_of_fav_id = tof.type_of_fav_id
It's a good idea to set up abbreviations of the table names as I have it here. You don't have to do that, but it's more concise and easier to work with. If you don't do it, you have to reference the full table name, to avoid ambiguity in field references: JOIN user_favorite on users.user_id = user_favorite.user_id, for example. That gets pretty long-winded.
If you don't include the tables when referencing the fields, the parser doesn't know which field you're referencing, since your field names aren't unique in your entire schema. So, you'll get an ambiguous field reference error.

How to get count by combining more than 2 tables in mysql

i have a table 'A' with status column, it can have 4 values. In table A i have table 'B's id, table B have table 'C's id. I want to get the status count FROM table 'A' by joining all these columns. The status column in table A is a foreign key from table 'D'. Table 'D' having status like 1-agreed, 2-not agreed etc
The question is missing some information that might be helpful. Particularly, what exactly you are wanting to count. (i.e. are you just trying to count ALL rows, or are you trying to count the number of rows in table A that have each status). I'll put together an answer that assumes that latter.
I'll also just assume that "id" is the primary key of its own table, and that id will be the id from other tables inside a table.
select A.statusField, count(*)
from A
join B on (A.Bid = B.id)
join C on (B.Cid = C.id)
group by A.statusField
Hope that helps.

Return records from one table where Field not found in another table

I'm so lost here I don't even know how to best title my question.
I am creating a simple dating site. I want the women to be able to block the men just like all other dating sites. When this happens, I don't want the womens' profiles to be returned in a query.
Table A
Members table containing all the profile information including a member name
Table B
Blocked members table containing the woman's name and the man's name for each case in which the woman has blocked a man
So, I want something like this:
$query = Return all records from table A where sex=female and there is no record in table B containing the woman's name and the man's name
I thought I would run a query against table B to retrieve all women who have blocked me, then run a query against table A to return all females in which the woman's username is NOT contained in the results of my first query. However, I can't figure out how to do this.
If I understand your question...seems like a simple join, no? Not sure if I'm misunderstanding. Something like this perhaps:
SELECT * FROM Table1 WHERE Table1.ID NOT IN (SELECT BLOCK_ID FROM table2)
So Table1 has all ID's of the women, and Table2 has all block id's (for example) and you want what is not in that? Obviously some changes required on top of this.
If you wanted to see a list of all the female members who had blocked the current user, you would use a query like:
SELECT member.*
FROM TableA member
JOIN TableB blocked ON (member.name = blocked.user_who_blocked)
WHERE member.sex = female
AND blocked.blocked_user_name = 'Joe McCurrentUser'
;
So, if you want to see the set of users where that is not the case, you use a LEFT JOIN and look for a null id.
SELECT member.*
FROM TableA member
LEFT JOIN TableB blocked ON (member.name = blocked.user_who_blocked)
WHERE member.sex = female
AND blocked.blocked_user_name = 'Joe McCurrentUser'
AND blocked.id IS NULL
;
You can modify as you wish to use the actual columns in your tables. Make sure you have indices on both the user_who_blocked and blocked_user_name columns in that table.
Would this work?
Select * from Table A
inner join Table B on a.womans_name = B.womans_name and B.mans_name="Mans Name"
where B.womans_name IS NULL
If Table B contains a record with the matching womans_name and mans_name then the join will create one record containing all the fields in Table A and Table B but the Where clause will reject this record because the womans_name from Table B will not be null. If Table B does not contain a matching record then all those fields will be null (including B.womans_name) so the Where clause is satisfied.

A MySQL query addressing three tables: How many from A are not in B or C?

I have a problem formulating a MySQL query to do the following task, although I have seen similar queries discussed here, they are sufficiently different from this one to snooker my attempts to transpose them. The problem is (fairly) simple to state. I have three tables, 'members', 'dog_shareoffered' and 'dog_sharewanted'. Members may have zero, one or more adverts for things they want to sell or want to buy, and the details are stored in the corresponding offered or wanted table, together with the id of the member who placed the ad. The column 'id' is unique to the member, and common to all three tables. The query I want is to ask how many members have NOT placed an ad in either table.
I have tried several ways of asking this. The closest I can get is a query that doesn't crash! (I am not a MySQL expert by any means). The following I have put together from what I gleaned from other examples, but it returns zero rows, where I know the result should be greater than zero.
SELECT id
FROM members
WHERE id IN (SELECT id
FROM dog_sharewanted
WHERE id IS NULL)
AND id IN (SELECT id
FROM dog_shareoffered
WHERE id IS NULL)
THis query looks pleasingly simple to understand, unlike the 'JOIN's' I've seen but I am guessing that maybe I need some sort of Join, but how would that look in this case?
If you want no ads in either table, then the sort of query you are after is:
SELECT id
FROM members
WHERE id NOT IN ( any id from any other table )
To select ids from other tables:
SELECT id
FROM <othertable>
Hence:
SELECT id
FROM members
WHERE id NOT IN (SELECT id FROM dog_shareoffered)
AND id NOT IN (SELECT id FROM dog_sharewanted)
I added the 'SELECT DISTINCT' because one member may put in many ads, but there's only one id. I used to have a SELECT DISTINCT in the subqueries above but as comments below mention, this is not necessary.
If you wanted to avoid a sub-query (a possible performance increase, depending..) you could use some LEFT JOINs:
SELECT members.id
FROM members
LEFT JOIN dog_shareoffered
ON dog_shareoffered.id = members.id
LEFT JOIN dog_sharewanted
ON dog_sharewanted.id = members.id
WHERE dog_shareoffered.id IS NULL
AND dog_sharewanted.id IS NULL
Why this works:
It takes the table members and joins it to the other two tables on the id column.
The LEFT JOIN means that if a member exists in the members table but not the table we're joining to (e.g. dog_shareoffered), then the corresponding dog_shareoffered columns will have NULL in them.
So, the WHERE condition picks out rows where there's a NULL id in both dog_shareoffered and dog_sharewanted, meaning we've found ids in members with no corresponding id in the other two tables.

mysql query with two tables?

I have two tables:
posts(id,user_id,event_id}
events(event_id,name,date]}
I want to make a query, to retrieve all the names of the events for a particular user_id say id number 2.
In pseudo-code lets say
select all the event names from posts where user_id=2
try:
select events.name from posts, events
where posts.event_id = events.event_id and user_id = 2
You will need to have something slightly different depending on how you want results with no matches to display.
select name from events join posts using (event_id) where user_id = 2