【问题标题】:MySQL 3 table search with one table not directly relatedMySQL 3表搜索与一张不直接相关的表
【发布时间】:2012-03-08 20:54:08
【问题描述】:

我有 3 张桌子:

  • wp_users - 存储所有用户的主要信息,
  • wp_usermeta - 存储有关用户的附加信息(名字/姓氏/等),
  • wp_friends - 存储来自与来自wp_users 的特定用户相关的第三方服务的朋友的信息

如果你不熟悉WordPress,你可以在http://codex.wordpress.org/images/9/9e/WP3.0-ERD.png看到这两个表的结构

我的自定义表wp_friends的结构如下:

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)
)`

uid 列对应于wp_users 表中的ID 列 - 这就是我确定哪个记录对应于哪个用户的方式。

我要做的是创建一个查询,该查询将在所有三个表中查找与关键字的匹配项。到目前为止,这是我带来的(第一部分是由 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

在上面的查询中,关键字是“nik”(也匹配user_login 列)。 fr.uid 部分是必需的,因此返回的结果仅适用于当前用户。查询失败的原因如下:

  • 它返回wp_friends 表中的所有行(因为user_login 列也匹配),具有wp_friends.uid = 2
  • 它返回具有wp_friends.uid = 2 但与wp_users.ID != 2 的用户匹配的行

是否可以创建一个查询,该查询将返回选定的列,但也可以防止重复?

【问题讨论】:

  • wp_socialaccess_friendswp_friends 表是相同的 - 只是一个错字。

标签: php mysql wordpress


【解决方案1】:

加入子选择怎么样:

SELECT 
    wp_users.ID,wp_users.display_name,wp_users.user_login,
    wp_users.user_email
    FROM wp_users

    INNER JOIN wp_usermeta ON (wp_users.ID = wp_usermeta.user_id)
    left join(
      select fr_id, uid,name,photo,service from wp_socialaccess_friends where
            uid = 2 and
            (fr_id LIKE '%nik%' OR name LIKE '%nik%')
        ) AS fr ON wp_users.ID = fr.uid 

    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')
    )

    GROUP BY wp_users.ID,fr.fr_id ORDER BY user_login ASC

【讨论】:

  • 它向我抛出了错误`在第 8(probably because you missed from 行的 'where uid = 2 and (fr_id LIKE '%nik%' OR name LIKE '%n' 附近使用正确的语法` ?) 。但是如果我添加FROM 我得到Unknown column 'fr.uid' in 'on clause',即使它是wp_socialaccess_friends.uid - 这对我来说没有任何意义,因为该列选择正确......
  • 我的错 - 我匆忙发帖。更新后的查询将uid 列添加到子选择中,我修复了缺少的from
  • 我将fr.*(我需要的那些)列添加到SELECT,它非常适合返回朋友,但只有当ID 列与@987654331 匹配时才会这样做@和user_login。我的意思是,如果我将关键字更改为不同于“nik”的内容,我将不会得到任何结果,因为user_login 列不再匹配。此外,搜索不再返回来自wp_users 的结果。就像我说的,我不太确定我想要的是否可以在单个查询中实现 - 你认为我应该做两个单独的查询然后用 PHP 对它们进行排序吗?
  • 可能是因为'2'是硬编码的,还是你在更改'nik'时改变了它?另一件事-fr.uid = wp_users.ID 对吗?如果是,请尝试将您的原始查询将LEFT JOIN wp_socialaccess_friends AS fr ON fr.uid = 2 更改为LEFT JOIN wp_socialaccess_friends AS fr ON fr.uid = wp_users.ID 并将OR ( fr.uid = 2 AND (fr.fr_id LIKE '%nik%' OR fr.name LIKE '%nik%')) 更改为OR ( fr.fr_id LIKE '%nik%' OR fr.name LIKE '%nik%')。似乎这两种方法中的一种应该有效。
  • 我相信它是硬编码的,因为我只需要用ID = 2找到用户的朋友,这使得wp_users.ID = wp_friends.uid = 2。我现在正在测试你的建议,但到目前为止没有多大成功......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多