【问题标题】:Using an aggregate string function with a subquery使用带有子查询的聚合字符串函数
【发布时间】:2019-06-03 18:13:29
【问题描述】:

此查询选择以下内容:

SELECT jobs.JobID, school.School_Name, 
       CONCAT(staff.First_Name, ' ', staff.Last_Name) AS 'Full_Name', 
       staff.Phone_Number, role.Role
  FROM jobs
 INNER JOIN school ON jobs.SchoolID=school.SchoolID
 INNER JOIN staff ON jobs.StaffID=staff.staffID
 INNER JOIN role ON jobs.roleID=role.roleID
 ORDER BY staff.StaffID asc


JOB ID  FULL NAME   ROLE
------  ---------   ----------
1       BOB         PRINCIPLE
2       BOB         TEACHER
3       JACK        TEACHER
4       SARAH       ACCOUNTANT
5       SARAH       NURSE

ROLE ID    ROLE
------    ----------
1         TEACHER
2         PRINCIPLE
4         ACCOUNTANT
5         NURSE

但是,我希望结果只取最大 RoleID 的角色:

BOB     PRINCIPLE
JACK    TEACHER
SARAH   NURSE

我知道我可以通过以下方式对它进行分组连接,但是之后我该怎么办?

SELECT Full_Name, GROUP_CONCAT(Role) AS Role
  FROM
 (
  SELECT jobs.JobID, school.School_Name, CONCAT(staff.First_Name, ' ', staff.Last_Name) 
     AS Full_Name, staff.Phone_Number, role.Role
    FROM jobs
   INNER JOIN school ON jobs.SchoolID=school.SchoolID
   INNER JOIN staff ON jobs.StaffID=staff.staffID
   INNER JOIN role ON jobs.roleID=role.roleID
   ORDER BY staff.StaffID asc
 ) q
GROUP BY Full_Name

据我了解,我需要一个子查询来过滤字符串吗?任何帮助表示赞赏,谢谢。

【问题讨论】:

  • 你为 SARAH 保留 Nurse 而不是保留 ACCOUNTANT 的逻辑是什么?
  • 在这种情况下,没有!但我想稍后处理一个用户可以在其中具有层次结构的角色的项目。如果用户有两个不同的规则,我只想选择最高层级中的一个。目前,这只是我想到的一个更简单的例子。
  • 抱歉,我保留 BOB 的第一个角色,它的 RoleID 比教师(第二个角色)更大

标签: mysql sql string subquery aggregate


【解决方案1】:

你也可以勾选这个选项 -

SELECT
jobs.JobID, 
school.School_Name, 
CONCAT(staff.First_Name, ' ', staff.Last_Name) AS 'Full_Name', 
staff.Phone_Number, 
role.Role
FROM staff
INNER JOIN jobs ON jobs.StaffID=staff.staffID
INNER JOIN school ON jobs.SchoolID=school.SchoolID
INNER JOIN role ON jobs.roleID=role.roleID
INNER JOIN (
    SELECT staff.staffID,MAX(Jobs.roleid) roleid
    FROM Staff INNER JOIN Jobs  ON jobs.StaffID=staff.staffID
    GROUP BY staff.staffID
 ) A ON jobs.StaffID = A.StaffID AND Jobs.roleID = A.roleid

【讨论】:

    【解决方案2】:

    使用相关子查询

     select a.* from (
        SELECT jobs.JobID, school.School_Name, 
               CONCAT(staff.First_Name, ' ', staff.Last_Name) AS 'Full_Name', 
               staff.Phone_Number, role.Role,staff.staffID,role.roleID
          FROM jobs
         INNER JOIN school ON jobs.SchoolID=school.SchoolID
         INNER JOIN staff ON jobs.StaffID=staff.staffID
         INNER JOIN role ON jobs.roleID=role.roleID
       ) a
     where (a.staffID,a.roleID) in (
          SELECT staff.staffID,MAX(Jobs.roleid) roleID
    FROM Staff INNER JOIN Jobs  ON jobs.StaffID=staff.staffID
    GROUP BY staff.staffID)
    

    如果是mysql 8.0或+,则使用rownumber()

            select * from
          (
              SELECT jobs.JobID, school.School_Name, 
               CONCAT(staff.First_Name, ' ', staff.Last_Name) AS 'Full_Name', 
               staff.Phone_Number, role.Role,
            row_number()over(partition by role.Role order by jobs.JobID desc) rn
          FROM jobs
         INNER JOIN school ON jobs.SchoolID=school.SchoolID
         INNER JOIN staff ON jobs.StaffID=staff.staffID
         INNER JOIN role ON jobs.roleID=role.roleID
         ) a where a.rn=1
    

    【讨论】:

    • 谢谢我的朋友,第一个查询确实有效,但是第二个查询在“row_number()over(partition by role.Role order by jobs.JobID desc) rn”周围有错误
    • @GoGoAllen for 2nd 需要更高的 mysql 版本
    • 糟糕!这非常接近,但是我不希望它按角色分组。例如。如果我有另一个人担任教师的最高角色,我也想向他们展示!
    • @GoGoAllen 你没有提到你需要考虑员工身份证所以我编辑了我的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 2011-04-17
    • 2013-04-25
    • 2021-10-30
    • 1970-01-01
    相关资源
    最近更新 更多