MySQL相关子查询:无法解析外表中的名称

时间:2014-07-17 12:45:47

标签: mysql correlated-subquery

我需要获取具有最高角色名称的用户列表。由于某些情况,一个用户只有一个角色。所以我有一些用户使用相同的

CONCAT(first_name, last_name) 

但使用不同的ID。可以简单地找到最高的角色,只是按升序排序所有用户的角色并获得第一个角色。 因此,我决定使用相关子查询来获得适当用户的最高角色ID。

但是在执行以下查询时

SELECT 
    u.id                    AS UserID,
    u.user_name             AS UserName,
    u.user_hash             AS Hash,
    u.first_name            AS FirstName,
    u.last_name             AS LastName,
    u.phone_mobile          AS PhoneMobile,
    u.address_city          AS City,
    u.address_state         AS State,
    ar.name                 AS RoleName
FROM
    users AS u
        JOIN
    acl_roles_users AS aru ON (u.id = aru.user_id AND aru.deleted = 0)
        JOIN
    acl_roles AS ar ON aru.role_id = ar.id
        JOIN
            (SELECT 
                ar2.id AS RoleID
            FROM
                users AS u2
            JOIN acl_roles_users AS aru2 ON (u2.id = aru2.user_id
                and aru2.deleted = 0)
            JOIN acl_roles AS ar2 ON (aru2.role_id = ar2.id
                AND ar2.deleted = 0)
            WHERE
                concat(u2.first_name, u2.last_name) = concat(u.first_name, u.last_name)
            ORDER BY ar2.name ASC
            LIMIT 1) AS temptbl ON RoleID = ar.id
WHERE
    u.status = 'Active' and u.deleted = 0
ORDER BY UserName
LIMIT 1000000; 

我收到错误消息

Error Code: 1054. Unknown column 'u.first_name' in 'where clause'

为什么'你' (用户)表在子查询中未解析?有没有想法如何重写查询?

3 个答案:

答案 0 :(得分:1)

您的查询不是corelated subquery。在temptbl中,无法查看u.first_name

如何使用EXISTS

SELECT 
    u.id                    AS UserID,
    u.user_name             AS UserName,
    u.user_hash             AS Hash,
    u.first_name            AS FirstName,
    u.last_name             AS LastName,
    u.phone_mobile          AS PhoneMobile,
    u.address_city          AS City,
    u.address_state         AS State,
    ar.name                 AS RoleName
FROM
    users AS u
        JOIN
    acl_roles_users AS aru ON (u.id = aru.user_id AND aru.deleted = 0)
        JOIN
    acl_roles AS ar ON aru.role_id = ar.id
WHERE
    u.status = 'Active' and u.deleted = 0
    AND EXISTS 
            (SELECT 
                1
            FROM
                users AS u2
            JOIN acl_roles_users AS aru2 ON (u2.id = aru2.user_id
                and aru2.deleted = 0)
            JOIN acl_roles AS ar2 ON (aru2.role_id = ar2.id
                AND ar2.deleted = 0)
            WHERE
                concat(u2.first_name, u2.last_name) = concat(u.first_name, u.last_name)
                AND ar2.id = ar.id
            ORDER BY ar2.name ASC
            LIMIT 1)
ORDER BY UserName
LIMIT 1000000; 

答案 1 :(得分:0)

你无法得到" u"子查询中的字段...也许你可以试试这个:

SELECT 
    u.id                    AS UserID,
    u.user_name             AS UserName,
    u.user_hash             AS Hash,
    u.first_name            AS FirstName,
    u.last_name             AS LastName,
    u.phone_mobile          AS PhoneMobile,
    u.address_city          AS City,
    u.address_state         AS State,
    ar.name                 AS RoleName
FROM
    users AS u
        JOIN
    acl_roles_users AS aru ON (u.id = aru.user_id AND aru.deleted = 0)
        JOIN
    acl_roles AS ar ON aru.role_id = ar.id
        JOIN
            (SELECT 
                ar2.id AS RoleID
            FROM
                users AS u2
            JOIN acl_roles_users AS aru2 ON (u2.id = aru2.user_id
                and aru2.deleted = 0)
            JOIN acl_roles AS ar2 ON (aru2.role_id = ar2.id
                AND ar2.deleted = 0)
            ORDER BY ar2.name ASC
            LIMIT 1) AS temptbl ON RoleID = ar.id 
            AND concat(temptbl.first_name, temptbl.last_name) = concat(u.first_name, u.last_name)
WHERE
    u.status = 'Active' and u.deleted = 0
ORDER BY UserName
LIMIT 1000000; 

如果这对您不起作用,也许您可​​以提供http://sqlfiddle.com/表格结构和一些虚拟数据......

答案 2 :(得分:0)

由于角色名称保留在VARCHAR列中,看起来像

  • ' 01 Mega boss',
  • ' 02 Super Boss',
  • ' 03标准老板',
  • ' 04 Micro Boss',
  • 等。

我只是重写一个小@Inos Heo版本以获得积极的结果:

SELECT u.id            AS UserID, 
       u.user_name     AS UserName, 
       u.user_hash     AS Hash, 
       u.first_name    AS FirstName, 
       u.last_name     AS LastName, 
       u.phone_mobile  AS PhoneMobile, 
       u.address_city  AS City, 
       u.address_state AS State, 
       ar.name         AS RoleName 
FROM   users AS u 
       JOIN acl_roles_users AS aru 
         ON ( u.id = aru.user_id 
              AND aru.deleted = 0 ) 
       JOIN acl_roles AS ar 
         ON aru.role_id = ar.id 
WHERE  u.status = 'Active' 
       AND u.deleted = 0 
       AND NOT EXISTS(SELECT 1 
                      FROM   users AS u2 
                             JOIN acl_roles_users AS aru2 
                               ON ( u2.id = aru2.user_id 
                                    AND aru2.deleted = 0 ) 
                             JOIN acl_roles AS ar2 
                               ON ( aru2.role_id = ar2.id 
                                    AND ar2.deleted = 0 ) 
                      WHERE  Concat(u2.first_name, u2.last_name) = 
                             Concat(u.first_name, u.last_name) 
                             AND ar2.id < ar.id 
                      ORDER  BY ar2.name ASC 
                      LIMIT  1) 
ORDER  BY Concat(lastname, firstname) 
LIMIT  1000000; 

注意使用NOT EXISTS而不是使用子查询WHERE子句。即过滤掉角色&#34;小于&#34;的行与外部查询相同的那些。

感谢您@Inos Heo指向正确的方向!