Mysql加入表 - 最佳实践?

时间:2012-11-27 11:31:54

标签: mysql sql

有5个表

  1. 用户个人数据(用户_记录= 120000)。
  2. 工作的用户(users_positions _ record = 150000)。
  3. 组织(组织_记录= 2500)。
  4. 分部(分部_记录= 3500)。
  5. 职位(职位_记录= 4500)。
  6. 我想加入这些表,但最好的查询是什么?

    我写了这个查询,但速度很慢:

    SELECT 
      * 
    FROM
      (SELECT 
        p.* 
      FROM
        `user_positions` p 
        LEFT JOIN `organizations` u_o 
          ON u_o.`id` = p.`org_title` 
        LEFT JOIN `divisions` u_d 
          ON u_d.`id` = p.`division` 
        LEFT JOIN `positions` u_p 
          ON u_p.`id` = p.`position` 
          WHERE u_o.`status` = 1 
      GROUP BY p.`PRN`) u_a 
      LEFT JOIN `users` u 
        ON u.`PRN` = u_a.`PRN` 
    

    示例 - 简单结构

    table users
    -- PRN --- FirstName --- Age....
    -- 001 --- david --- 24 ....
    -- 052 --- george --- 27 ....
    
    
    table users_positions
    -- PRN --- Organization_ID --- Division_ID --- Positionn_ID....
    -- 001 --- 1 --- 5 --- 1....
    -- 001 --- 2 --- 10 --- 5....
    -- 052 --- 1 --- 1 --- 1....
    
    table organizations
    -- ID --- Name ....
    -- 1 --- test 1 ....
    -- 2 --- test 2 ....
    
    table divisions
    -- ID --- Name --- Age....
    -- 1 --- IT Department ....
    -- 5 --- Sale Department ....
    -- 10 --- Administration Department ....
    
    table positions
    -- ID --- Name --- Age....
    -- 1 --- Programmer ....
    -- 5 --- Manager ....
    

1 个答案:

答案 0 :(得分:2)

我不确定您在查询中使用GROUP BY的原因。当您在查询中使用聚合函数时,通常会使用GROUP BY。但我会说你可以使用以下内容:

select *
from users u
left join users_positions up
  on u.PRN = up.PRN
left join positions p
  on up.id = p.position
left join organizations o
  on p.org_title = o.id
left join divisions d
  on p.division = d.id

使用您提供的示例数据进行编辑,以下是您可以使用的查询示例:

select u.prn,
  u.firstname,
  u.age,
  o.name orgName,
  p.name positionName,
  d.name divisionName
from users u
left join users_positions up
  on u.PRN = up.PRN
left join organizations o
  on up.Organization_ID = o.id
left join positions p
  on up.Positionn_ID = p.id
left join divisions d
  on up.Division_ID = d.id

请参阅SQL Fiddle with Demo

此查询的结果是:

| PRN | FIRSTNAME | AGE | ORGNAME | POSITIONNAME |              DIVISIONNAME |
------------------------------------------------------------------------------
| 001 |     david |  24 |  test 1 |   Programmer |           Sale Department |
| 001 |     david |  24 |  test 2 |      Manager | Administration Department |
| 052 |    george |  27 |  test 1 |   Programmer |             IT Department |

如果您只想为每个用户返回一个组织等,那么您需要决定如何确定要返回的正确结果。例如,如果您只想返回每个用户max(Organization_ID),那么您可以使用与此类似的内容:

select u.prn,
  u.firstname,
  u.age,
  o.name orgName,
  p.name positionName,
  d.name divisionName
from users u
left join
(
  select max(Organization_ID) Organization_ID, PRN
  from users_positions
  group by PRN
) up1
  on u.PRN = up1.PRN
left join users_positions up2
  on up1.PRN = up2.prn
  and up1.Organization_ID = up2.Organization_ID
left join organizations o
  on up2.Organization_ID = o.id
left join positions p
  on up2.Positionn_ID = p.id
left join divisions d
  on up2.Division_ID = d.id

请参阅SQL Fiddle with Demo

结果:

| PRN | FIRSTNAME | AGE | ORGNAME | POSITIONNAME |              DIVISIONNAME |
------------------------------------------------------------------------------
| 001 |     david |  24 |  test 2 |      Manager | Administration Department |
| 052 |    george |  27 |  test 1 |   Programmer |             IT Department |