【问题标题】:Select query in two tables in MySQL在 MySQL 的两个表中选择查询
【发布时间】:2014-01-16 09:09:30
【问题描述】:

我正在运行这个查询

select * from user_meta JOIN user ON user_meta.userid=user.userid where user_meta.userid=9

但这不是我想要的结果,它返回多行。

我的一张桌子看起来像这个名字user_meta

umeta_id     userid      meta_key       meta_value
 1              9         mobile        123324
 2              9         address       some address
 3              9         city          some city
 4              9         country       some country
 5              9         occupation    some details
 6              9         website       someurl
 7              9         mobile        123324
 8              9         address       some address
 9              9         city          some city
 10             10        country       some country
 11             10        occupation    some details
 12             10        website       someurl

另一个表看起来像这个名字user

userid          username      fullname      email              role
  9             someuser       john Doe    123324@gmail.com    admin

如何让它选择查询,以便可以从两个表中获取与 userid 9 相关的所有值并使其看起来像这样

期望的输出:

userid          username      fullname      email              role      Mobile     address     city     country    occupation     website
  9             someuser       john Doe    123324@gmail.com    admin    123123     someaddres    Somecity    somecountry    some details    someurl

谢谢! (提前!)

【问题讨论】:

  • 您的查询看起来应该返回用户 ID 9 的所有行(即 9 行)。你能举例说明你希望它输出什么吗?
  • 给出你想要的输出模式?
  • 检查这个sqlfiddle.com/#!2/39861/2,这可能对你有帮助。
  • 庆祝! EAV 数据模型的乐趣!

标签: php mysql sql


【解决方案1】:
SELECT 
    *
FROM
    user
        INNER JOIN
    user_meta ON user_meta.userid = user.userid
WHERE
    user.userid = 9

上面的答案是关于你最初的要求。但是根据您的新要求,它不能通过简单的查询来完成,它需要是动态的,在这里我为您创建了演示,您可以使用它

http://sqlfiddle.com/#!2/39861/2

【讨论】:

  • 返回多行值。我只想要单行。
  • 你能发布你想要的输出信息吗,inner join 会对表做join,并找到所有匹配的join行。在 user_meta 中,userid = 9 有多行,因此它以这种方式返回。还有另一种使用 GROUP_CONCAT() 函数的方法,但这会将数据与分隔符连接在一行中,例如移动、地址、...等 meta_key 使用 group by。
  • 是的,但我想要类似于我上面提到的“所需输出”的东西。谢谢你!等待您的回复。
【解决方案2】:

为您提供所需的输出(但这并不灵活,因此如果您添加更多要输出的详细信息,将无法应对):-

SELECT user.userid, 
        user.username, 
        user.fullname, 
        user.email, 
        user.role, 
        mobile_meta.meta_value AS `Mobile`, 
        address_metameta_value AS `Address`, 
        city_metameta_value AS `City`, 
        country_metameta_value AS `Country`, 
        occupation_metameta_value AS `Occupation`, 
        website_metameta_value AS `Website`
FROM user
LEFT OUTER JOIN user_meta AS mobile_meta ON mobile_meta.userid=user.userid AND mobile_meta.meta_key = 'mobile'
LEFT OUTER JOIN user_meta AS address_meta ON address_meta.userid=user.userid AND address_meta.meta_key = 'address'
LEFT OUTER JOIN user_meta AS city_meta ON city_meta.userid=user.userid AND city_meta.meta_key = 'city'
LEFT OUTER JOIN user_meta AS country_meta ON country_meta.userid=user.userid AND country_meta.meta_key = 'country'
LEFT OUTER JOIN user_meta AS occupation_meta ON occupation_meta.userid=user.userid AND occupation_meta.meta_key = 'occupation'
LEFT OUTER JOIN user_meta AS website_meta ON website_meta.userid=user.userid AND website_meta.meta_key = 'website'
WHERE user.userid=9

【讨论】:

  • 是的,我正在尝试为此创建一个动态查询,请参阅此处sqlfiddle.com/#!2/13703/11,不确定哪里出了问题,如果有人可以编辑它,这可能会解决问题。
  • 应该可以。但是我认为您遇到的问题是一个非常简单的错字。您已经为用户 id 1 设置了测试数据,但您为用户 id 9 选择了测试数据,因此没有返回记录。请注意,您可以使用我之前提出的 GROUP_CONCAT 建议来执行此操作,提取脚本中的详细信息。
  • 啊@Kickstart 非常感谢它现在工作了,我的错,我快疯了。 sqlfiddle.com/#!2/39861/2 这是输出。我使用了这里建议的逻辑stackoverflow.com/questions/15977322/…
  • 这是一种完全有效的方法,尽管大多数人在看到您的代码时会感到困惑!不利的一面是它有效地执行了 2 个查询。
  • 是的,如果我们真的不知道第二张表中的行数,我们会寻找更好的方法。您在回答中提到了这一点。
【解决方案3】:
SELECT * FROM user_meta um, user u WHERE um.userid = u.userid

【讨论】:

    【解决方案4】:

    就这么简单:

    select * from user_meta, user where user_meta.userid=9 
    and user_meta.userid=user.userid
    

    【讨论】:

      【解决方案5】:
      select 
          user_meta.umeta_id,
          user_meta.userid,
          user_meta.meta_key,
          user_meta.meta_value,
          user.userid,
          user.username,
          user.fullname,
          user.email,
          user.role
      from
          user_meta
              LEFT JOIN
          user ON user_meta.userid = user.userid
      where
          user_meta.userid = 9
      

      【讨论】:

        【解决方案6】:

        将其缩减为单行的唯一真正方法是使用聚合函数

        例如,对字段中的详细信息进行分组

        SELECT user.userid, user.username, user.fullname, user.email, user.role, GROUP_CONCAT(CONCAT_WS('-', user_meta.umeta_id, user_meta.meta_key, user_meta.meta_value))
        FROM user_meta 
        INNER JOIN user ON user_meta.userid=user.userid 
        WHERE user_meta.userid=9
        GROUP BY user.userid, user.username, user.fullname, user.email, user.role
        

        【讨论】:

          【解决方案7】:

          如果你只想要 user_meta 表,所有值都意味着使用这个。

          select meta.* from user_meta AS meta JOIN user AS us ON meta.userid=us.userid where meta.userid=9
          

          如果你只想要用户表,所有值都意味着使用这个。

          select us.* from user_meta AS meta JOIN user AS us ON meta.userid=us.userid where meta.userid=9
          

          如果你想要两者都意味着这样提及

          select 
              meta.umeta_id,
              meta.userid, // only one userid is enough
              meta.meta_key,
              meta.meta_value,
              us.username,
              us.fullname,
              us.email,
              us.role from user_meta JOIN
              user ON meta.userid = us.userid
          

          【讨论】:

          • 谢谢!为您的友好答复。你能建议我一些与所需输出相关的东西吗?
          【解决方案8】:

          从用户 U 中选择 * INNER JOIN Meta_Users M ON U.userid = M.userid
          WHERE U.userid = 9

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-21
            • 1970-01-01
            相关资源
            最近更新 更多