I have 3 tables :
wp_users– stores main information about all users,wp_usermeta– stores additional information about users(first/last name/etc),wp_friends– stores information about friends from third party services related to a specific user fromwp_users
If you are not familiar with WordPress, you can see the structure of both tables at http://codex.wordpress.org/images/9/9e/WP3.0-ERD.png
The structure of my custom table wp_friends is as follows:
CREATE TABLE wp_friends (
id bigint(20) unsigned NOT NULL auto_increment,
uid bigint(20) unsigned NOT NULL default '0',
fr_id VARCHAR (60) NOT NULL default '',
service VARCHAR (20) NOT NULL default '',
name VARCHAR (80) NOT NULL default '',
photo VARCHAR (255) NOT NULL default '',
PRIMARY KEY (id),
KEY uid (uid),
KEY fr_id (fr_id),
KEY service (service)
)`
The uid column is corresponds to the ID column in the wp_users table – this is how I determine which record corresponds to which user.
What I’m trying to do is to create a query that will look in all of the three tables for a match against a keyword. Here is what I’ve come with so far(the first part was generated by a search function of WordPress):
SELECT
wp_users.ID,wp_users.display_name,wp_users.user_login,
wp_users.user_email,fr.fr_id,fr.name,fr.photo,fr.service
FROM wp_users
INNER JOIN wp_usermeta ON (wp_users.ID = wp_usermeta.user_id)
LEFT JOIN wp_socialaccess_friends AS fr ON fr.uid = 2
WHERE
(
(user_login LIKE '%nik%' OR user_nicename LIKE '%nik%')
AND
(wp_usermeta.meta_key = 'wp_user_level' AND CAST(wp_usermeta.meta_value AS CHAR) != '0')
)
OR ( fr.uid = 2 AND (fr.fr_id LIKE '%nik%' OR fr.name LIKE '%nik%'))
GROUP BY wp_users.ID,fr.fr_id ORDER BY user_login ASC
In the above query, the keyword is “nik”(which also matches a user_login column). The fr.uid part is needed so the returned results are only for the current user. The query fails in the following ways:
- It returns all rows from the
wp_friendstable(because theuser_logincolumn is matched as well), that havewp_friends.uid = 2 - It returns rows that have
wp_friends.uid = 2but matched with users wherewp_users.ID != 2
Is it possible to create a single query, that would return the selected columns, but will also prevent duplicates?
What about joining on a sub-select like: