I have two tables, named voter and log_vote. Voter contains data of voters while log_vote contains data of voters who have voted.
Now I'm trying to show the voters who haven't voted. I have tried using JOIN in both tables but it will fail since JOIN clause only shows voters that have voted of course.
Here's the code snippet which I've tried:
SELECT * FROM voter INNER JOIN log_vote ON log_vote.nim = voter.nim
How to show only voters who haven't voted? Is using JOIN a correct way to do? Thanks in advance, I will really appreciate for the answer!
*NOTE: I'm using PHP Technology. Wonder if there's any way that PHP can do with my problem.
This can be done with a LEFT JOIN, that way the join condition won't filter those who dont answer it, and then you filter all those who didn't have a match like this:
SELECT voter.* FROM voter
LEFT JOIN log_vote ON log_vote.nim = voter.nim
WHERE log_vote.nim is null
I think the most direct method is not exists:
select v.*
from voter v
where not exists (select 1 from log_vote lv where lv.nim = v.nim);
If you want to use join, then the appropriate version is left join:
select v.*
from voter v left join
log_vote lv
on lv.nim = v.nim
where lv.nim is null;
You can do this also..
SELECT * FROM voter LEFT JOIN log_vote ON log_vote.nim = voter.nim
WHERE log_vote.nim IS NULL
you can use
NOT IN
this code should work!
SELECT * FROM voter v WHERE v.nim NOT IN (SELECT lv.nim FROM log_vote lv)
you should give more information about the attribute of each tables are you sure they have the attribute nim in each?
Related
my query looks like that:
SELECT
count(users.id)
FROM users
LEFT JOIN mail_sender_jobs_actions ON mail_sender_jobs_actions.userID = users.id
LEFT JOIN table2 ON table2.userID = users.id
LEFT JOIN table3 ON table3.userID = users.id
WHERE {$flexibleWhereClause}
Now, the mail_sender_jobs_actions table CAN (doesnt need to return anything) return multiple entries. I dont want to group the results but still limit the returns of mail_sender_jobs_actions to 1 so I dont get duplicates... Otherwise the count wouldnt work properly.
Scraped the whole web and found nothing working for me as I want to keep the where clause flexible. Any solution?
EDIT
so to explain the situation. We have a table with users (users). We have a table with actions (mail_seder_jobs_actions). We have other tables related to that query which are not relevant (table1, table2, table3)
If a user does an action, an entry is being created in the actions table.
The where clause is flexible, meaning it is possible that somebody wants to only show users with a specific action.
It is also possible that an action is not relevant to the user, so this entry gets ignored.
With where criteria you have there is no point using left join, since the where criteria applies to the table on the right hand side, effectively turning the left join into an inner join.
Apparently yo do not use any columns from the right hand side table, so instead of using joins, I would use an exists subquery.
SELECT
1 as count,
users.email
FROM users
WHERE EXISTS (SELECT 1
FROM mail_sender_jobs_actions
WHERE mail_sender_jobs_actions.userID = users.id
AND mail_sender_jobs_actions.type = '1'
AND mail_sender_jobs_actions.jobID = '106'
AND {$flexibleWhereClause})
However, there is little point in having the count() because it will always return 1. If you want to count how many records each user has in the mail_sender_jobs_actions table, then you have to use left join, group by, and move the where criteria into the join condition:
SELECT
count(mail_sender_jobs_actions.userID),
users.email
FROM users
LEFT JOIN mail_sender_jobs_actions ON mail_sender_jobs_actions.userID = users.id
AND mail_sender_jobs_actions.type = '1'
AND mail_sender_jobs_actions.jobID = '106'
AND {$flexibleWhereClause}
GROUP BY users.email
I have been looking and cant find an answer to what im trying to do.
I dont know if a query can be created in the following way.
$sql_call = "SELECT table.item,table.item,table.item FROM cust
LEFT JOIN contact ON cust.id = contact.client_id
LEFT JOIN survey_audit ON cust.id = survey_audit.cust_id
WHERE cust.clinic='$clinic_id' AND contact.participate='1' AND survey_audit.survey_id != '$post_survey_id'";
The query above, does not do what Im trying to do, and that is:
Get data from tables WHERE cust.clinic=something AND contact.participate=something AND (this is the part im not sure about) inside Survey_audit table, there is no row with this id.
Is it possible to ask sql to find a result where something=something AND is no row in specific table?
You are sort of on the right track. You simply need to look for cases where survey_audit.survey_id is NULL.
SELECT table.item,table.item,table.item
FROM cust
LEFT JOIN contact
ON cust.id = contact.client_id
LEFT JOIN survey_audit
ON cust.id = survey_audit.cust_id
WHERE cust.clinic='$clinic_id'
AND contact.participate='1'
AND survey_audit.survey_id IS NULL
Here is a very useful resource for helping you determine how to form more complex join scenarios. Your case is the 4th example on this page.
http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
You can exclude all the elements of the table using a subquery:
$sql_call = "SELECT table.item,table.item,table.item FROM cust
LEFT JOIN contact ON cust.id = contact.client_id
LEFT JOIN survey_audit ON cust.id = survey_audit.cust_id
WHERE cust.clinic='$clinic_id' AND contact.participate='1' AND survey_audit.survey_id NOT IN (SELECT survey_id FROM Survey_audit);
Yes it is possible, you should read more about other types of joins in mysql there are 4 types of joins
INNER JOIN (JOIN) - matching id's in both tables
LEFT JOIN - matching id in table A and can be null in Table B
RIGHT JOIN - matching id in table B and can be null Table A
OUTER JOIN - can be null in both tables
Recommend you to read the following article
http://www.sitepoint.com/understanding-sql-joins-mysql-database/
So for your question I guess you should use RIGHT JOIN survey_audit instead of LEFT JOIN survey_audit
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.
I'm having a problem with my SELECT sql statement and I haven't figured it out yet. When I print out the results using mysql_fetch_assoc() function, I get repetitive rows/records. A record is repeated 13 times. I don't know why and I have done it right as far as my knowledge tells me.
The following is my sql query:
SELECT
members.member_id,
members.firstname,
members.lastname,
billing_details.Street_Address,
billing_details.Mobile_No,
orders_details.*,
food_details.*,
categories.*,
cart_details.*,
quantities.*
FROM
members, billing_details, orders_details, categories,
quantities, food_details, cart_details
WHERE
members.member_id=orders_details.member_id AND
billing_details.billing_id=orders_details.billing_id AND
orders_details.cart_id=cart_details.cart_id AND
cart_details.food_id=food_details.food_id AND
cart_details.quantity_id=quantities.quantity_id
You don't have "categories" in your WHERE clause. I am guessing you have 13 categories? If you need a better explanation, let me know.
Use SELECT DISTINCT.
Please Note
Using the mysql_* libraries is bad practise. They are Deprecated and should be replaced by either the mysqli_* libraries or a PDO object.
Why dont you make left Joins like below
SELECT members.member_id, members.firstname, members.lastname, billing_details.Street_Address, billing_details.Mobile_No, orders_details.*, food_details.*, categories.*, cart_details.*, quantities.* FROM members as m
Left join billing_details as b ON b.billing_id=m.?
LEFT JOIN orders_details as o ON o.cart_id=m.?
LEFT JOIN food_details as f ON f.f_id =m.?
LEFT JOIN cart_details as c ON c.?=?
LEFT JOIN quantitiesas q ON q.?=?
LEFT JOIN categories as cat ON cat.?=?
If you only want each member_id to appear once, you can use DISTINCT:
SELECT DISTINCT members.member_id, ...
You can also use JOIN USING to avoid repetition (DRY):
http://dev.mysql.com/doc/refman/5.7/en/join.html (search for USING(column_list))
That way, you'd also have noticed the msising predicate, since it would be right next to the joined table name.
I need 3 tables that are all relevant to the same thing.
For instance, 1 has user information, 1 has page information for that user and the other has page options for that user.
all connected through user_id
is is possible to do this.
SELECT *
FROM users
LEFT JOIN page_info ON users.id=page_info.user_id
RIGHT JOIN page_settings ON user.id=page_settings.user_id
WHERE users.id=$id
or will i be defeated to using 2 queries
Thanks
I think you misunderstand what a LEFT and RIGHT outer join do: read A Visual Explanation of SQL Joins.
In your case, with the users table coming first (i.e. to the "left" of all others), I suspect you want both joins to be LEFT outer joins? That is:
SELECT *
FROM users
LEFT JOIN page_info ON users.id = page_info.user_id
LEFT JOIN page_settings ON users.id = page_settings.user_id
WHERE users.id = $id
Yes, you can.
http://dev.mysql.com/doc/refman/5.0/en/join.html