【问题标题】:2 Nested queries from the same table?2 来自同一张表的嵌套查询?
【发布时间】:2020-08-07 21:48:24
【问题描述】:

所以我有 3 张桌子

用户表

UserId User

语言表

LanguageId Language Fluency

用户语言表

UserLanguageId UserId LanguageId

基本上我需要的是一个查询,其中 PriLang 是 Fl​​uency='Primary' 而 SecLang 是 Fl​​uency='Secondary' 并且看起来像这样

+------------+-----------------+-----------+
| User       | PriLang         | SecLang   |
+------------+-----------------+-----------+
| Jimbo      | English         | Spanish   |
+------------+-----------------+-----------+
| Norm       | French          | Spanish   |
+------------+-----------------+-----------+
| Kathy      | Japanese        | Italian   |
+------------+-----------------+-----------+

【问题讨论】:

    标签: mysql sql join pivot


    【解决方案1】:

    在我看来,最直接的方法涉及到 user_languages 表的两个连接,以及每个连接到 langauges 表的连接。

    select  usr.User, lg1.Language PriLang, lg2.Language SecLang 
    from users usr
     left join user_languages ul1
      on ul1.userId = usr.userId
       and ul1.Fluency='Primary'
     left join user_languages ul2
      on ul2.userId = usr.userId
       and ul2.Fluency='Secondary'
     left join languages lg1
      on lg1.languageId = ul1.languageId
     left join languages lg2
      on lg2.languageId = ul2.languageId
    

    【讨论】:

    • 谢谢,完全按预期工作。我不知道你可以在 ul2 下像你那样拥有流畅条件。
    • 很高兴我能帮上忙!
    【解决方案2】:

    一个选项使用条件聚合:

    select 
        u.user,
        max(case when l.fluency = 'Primary' then l.language end) as pri_lang,
        max(case when l.fluency = 'Secondary' then l.language end) as sec_lang
    from users u 
    left join user_languages ul on ul.user_id = u.user_id
    left join languages l on l.language_id = ul.language_id
    group by u.user_id, u.user
    

    【讨论】:

      【解决方案3】:

      根据您的设置,可能是这样的;这应该让您使用subquery 关闭:

      SELECT u.User,
             (SELECT lt.Language
              FROM Language_table lt
                  JOIN UserLanguage_table ult ON lt.LanguageId = ult.LanguageId 
                  JOIN User_table u ON ult.UserId = u.UserId
              WHERE lt.Language_Fluency = 'primary'
                  AND ult.UserId = u.UserId
                  AND lt.LanguageId = ult.LanguageId) AS primary_lang,
             (SELECT lt.Language
              FROM Language_table lt
                  JOIN UserLanguage_table ult ON lt.LanguageId = ult.LanguageId 
                  JOIN User_table u ON ult.UserId = u.UserId
              WHERE lt.Language_Fluency = 'secondary'
                  AND ult.UserId = u.UserId
                  AND lt.LanguageId = ult.LanguageId) AS secondary_lang
      FROM User_table u;
      

      【讨论】:

      • 这不会返回正确的结果。您必须将内联查询与用户相关联,如 WHERE Language_Fluency = 'Primary' and userID = u.userID
      • 谢谢你;为了我理解相关子查询的好处,我们是否必须链接 WHERE 子句中的其他 2 个表,或者只是像你一样的单个表?
      • @tlk27:实际上只是删除整个连接子句并参考 user_id 和其他过滤器在内联查询中使用。
      • @tlk27: 只是想更新一下,我建议对查询进行一些更改,1. Language_table 只能在内联查询中使用一次 2. 当我们将内联查询作为列时,我们不会'不需要左连接而不是简单连接就足够了,因为如果连接条件匹配,则返回结果,否则返回 null。
      • @Sujitmohanty30 感谢您的知识和建议。感谢您抽出宝贵时间提供改进此解决方案所需的信息和见解
      猜你喜欢
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多