I have the following query:
SELECT u.user_id, u.username, u.email
hp.homepage_id
FROM table_u u
LEFT JOIN table_hp hp
ON (u.user_id = hp.user_id)
WHERE u.blocked = 'N'
AND u.email LIKE 'someemailaddress'
I am joining on the user_id column, for the given emailadress I know both properties are the same so I should get a result but still I don't get any result... so what is wrong with this query?
Put the '%' before and after in the LIKE clause - see below
SELECT u.user_id, u.username, u.email
hp.homepage_id
FROM table_u u
LEFT JOIN table_hp hp
ON (u.user_id = hp.user_id)
WHERE u.blocked = 'N'
AND u.email LIKE '%someemailaddress%'
Did you try the query without LEFT JOIN ??
SELECT u.user_id, u.username, u.email
FROM table_u u
WHERE u.blocked ='N'
AND u.email LIKE 'someemailaddress'
Does it return any result? Cause LEFT JOIN just append data for the existing data from your "base table" .. so if the LEFT JOIN didn't find any user_id in table_hp there should be some data returned, if there are some from the query above
The point was how some data was stored in the database... Seems that in an old (buggy) version of the application data was stored without decent trimming etc. The issue was the field was stored in with a whitespace...
Stupid... should/must had checked the actual data that was stored...
Related
SELECT DISTINCT u.id AS userId,u.type AS userType
FROM User AS u,Personal AS p,Company AS c
WHERE (p.realName LIKE '%adf%' AND u.type=1 AND u.id=p.userId)
OR (c.name LIKE '%grge%' AND u.id=c.userId)
LIMIT 0 , 10000
You can write your query as:
SELECT DISTINCT u.id AS userId,u.type AS userType
FROM User AS u inner join Personal AS p on u.id=p.userId
inner join Company AS c on u.id=c.userId
where p.realName LIKE '%adf%' or c.name LIKE '%grge%'
LIMIT 0 , 10000
Try to avoid comma seperated JOINS
You appear to be doing a quite hideous cross join, and then selectively narrowing down the records in the WHERE clause.
It is probably better to do 2 queries and union the results together. Each query can do one proper join. It is still going to have to access one column using the LIKE, and with a leading wild card that is not going to be quick (it can't use indexes).
SELECT u.id AS userId,
u.type AS userType
FROM User AS u
INNER JOIN Personal AS p
ON u.id = p.userId
WHERE p.realName LIKE '%adf%'
AND u.type = 1
UNION
SELECT u.id AS userId,
u.type AS userType
FROM User AS u
INNER JOIN Company AS c
ON u.id=c.userId
WHERE c.name LIKE '%grge%'
LIMIT 0 , 10000
I'm using this query:
SELECT u.name, u.lastname, u.username
FROM users AS u, inmeeting AS i
WHERE i.memo='7' AND i.user = u.keyid
To get all user data if the keyid for that user is in the table inmeeting (which means the user was present) for the id of that particular meeting (this would be why i.memo = 7).
Now I want to write another query that gets me all the user data of all OTHER people that were not in that meeting. I wrote this like so:
SELECT u.name, u.lastname, u.username
FROM users AS u, inmeeting AS i
WHERE i.memo='7' AND i.user <> u.keyid
However this query gets me EVERY user twice!! I don't understand what I'm doing wrong or how to do it right (well, I supposed this last one can be done with a subquery, but I was hoping for something a little bit more elegant). Any ideas?
Best to use a LEFT OUTER JOIN and check for no match (ie, check for NULL in the WHERE clause for a column in the LEFT JOINED table):-
SELECT u.name, u.lastname, u.username
FROM users AS u
LEFT OUTER JOIN inmeeting AS i
ON i.user = u.keyid
AND i.memo='7'
WHERE i.user IS NULL;
You could try it with
SELECT
u.name, u.lastname, u.username
FROM
users AS u
WHERE
u.keyid NOT IN (SELECT i.user FROM inmeeting WHERE i.memo='7')
I've never been all that great with much more then regular select queries. I have a new project that has users, roles and assigned_roles (lookup table for users with roles).
I want to group_concat the roles.name so that my result shows me what roles each user has assigned.
I've tried several things:
select users.id, users.displayname,users.email, rolenames from `users`
left join `assigned_roles` on `assigned_roles`.`user_id` = `users`.`id`
left join (SELECT `id`, group_concat(`roles`.`name`) as `rolenames` FROM `roles`) as uroles ON `assigned_roles`.`role_id` = `uroles`.`id`
This gives me the grouped role names but shows me duplicate entries if a user has two roles, so the second row in the result shows the same user but no role names.
select users.id, users.displayname,users.email, rolenames from `users`
join `assigned_roles` on `assigned_roles`.`user_id` = `users`.`id`
join (SELECT `id`, group_concat(`roles`.`name`) as `rolenames` FROM `roles`) as uroles ON `assigned_roles`.`role_id` = `uroles`.`id`
Just regular joins shows me what I want but wont lists users who do not have any assigned.roles, so its not complete.
I'll keep plugging away but I thought stack could help, hopefully I'll learn a bit more about joins today.
Thank you.
For GROUP CONCAT to work in this scenario, you'll need a GROUP BY to get the group info per user, something like;
SELECT u.id, u.displayname, u.email, GROUP_CONCAT(r.name) rolenames
FROM users u
LEFT JOIN assigned_roles ar ON ar.user_id = u.id
LEFT JOIN roles r ON r.id = ar.role_id
GROUP BY u.id, u.displayname, u.email
The following query does what I want. It returns all the resuls in the users table and then if there is a match in the details tble, returns the relevant data
users
id|username
details
id|userid|firstname|lastname
$sql = "SELECT u.*, d.*
FROM `users` u
LEFT JOIN `details` d on
u.id = d.userid
ORDER BY $strorder";
However, when I try to join an additonal table where I want to do the same thing--return all the results of the users table and if there is a match in the third table, return the relevant data (total followers of this user)--it only returns one record.
3rd table
follow
id|followerid|followedid
$sql = "SELECT u.*, d.*, COUNT(f.id)
FROM `users` u
LEFT JOIN `details` d on
u.id = d.userid
LEFT JOIN `follow` f on
u.id = f.followedid
ORDER BY $strorder";
Can anyone see what I am doing wrong? Thanks in advance for any suggestions.
Many thanks.
Try to avoid * to select fields, it will be clearer to group your datas (even if mysql is quite permissive with groupings).
When you have an aggregate function (like COUNT, SUM), the other "non aggregated" requested fields should be in a GROUP BY clause.
Mysql don't force you to GROUP BY all the fields, but... I think it's quite a good habit to be "as ANSI as possible" (usefull when you use another DBMS)
SELECT u.id, u.username, d.firstname, d.lastname, count(*) as numberfollowers
FROM user u
LEFT JOIN details d on u.id = d.userid
LEFT JOIN follow f on u.id = f.followedid
GROUP BY u.id, u.username, d.firstname, d.lastname --or just GROUP BY u.id with Mysql
ORDER BY count(*) desc
COUNT being an aggregate function, when selected with other columns, requires you to group your results by those other columns in the select list.
You should rewrite your query with columns that you want to select from users and details and group by those columns.
I want to join two tables to get data from both tables, for example, consider two following tables:
Table users:
ID user_name email ... ....
Table messages:
ID user_name message ... ...
The user_name is common column in both tables. How can I join both tables so that I can get the data from both tables. For example, I want to select the "message" from Table messages and "email" from table "users" where user_name is abc.
Use:
SELECT u.*, m.*
FROM USERS u
JOIN MESSAGES m ON m.user_name = u.user_name
WHERE u.user_name = 'abc'
...to see all the users who have messages in the tables. That means that users without messages will not appear in the output - so you might want to use the following instead:
SELECT u.*, m.*
FROM USERS u
LEFT JOIN MESSAGES m ON m.user_name = u.user_name
WHERE u.user_name = 'abc'
I recommend:
reading the Visual Explanation of JOINs.
not using a user_name as the criteria to link data between tables, because usernames can change which would require updating all the supporting tables in this example.
not using ANSI-89 join syntax, because it doesn't support OUTER joins and should be considered deprecated for that fact. My example is ANSI-92 syntax, and widely supported.
If you take a look at the MySQL website, there are a lot of examples on there. For the most part, people would be happier to answer if you had show some queries you'd tried and not got the results you wanted.
select users.user_name, users.email, messages.message from users,messages where users.user_name=messages.user_name where users.user_name='abc'
This is a fairly elementary SQL statement. There's a lot of clever stuff you can do. You would be wise to go see what else you can do, as rather than embed the 'abc' part you can use parameters etc.
SELECT message, email
FROM users U, messages M
WHERE U.user_name = 'abc' AND U.user_name = M.user_name;
select m.message, u.email
from
messages m join users u on
m.user_name = u.user_name
where
u.user_name = 'abc'
If you want the data that matches in both tables (so not a user without a message):
SELECT * FROM users u, messages m WHERE u.user_name = m.user_name;
If you want all users regardless of messages and messages for those users who have them:
SELECT * FROM users u LEFT JOIN (messages m) ON (u.user_name = m.user_name);
EDIT: Sorry, I misread.
SELECT * FROM users u, messages m WHERE u.user_name = m.user_name AND u.user_name = "abc";