【问题标题】:Multiple join on same table同一表上的多个连接
【发布时间】:2025-12-15 19:45:01
【问题描述】:

我的架构是

CREATE TABLE IF NOT EXISTS `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(120) NOT NULL,
   PRIMARY KEY (`id`)
 ); 

 CREATE TABLE IF NOT EXISTS `reseller_did` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `phone` int(11) NOT NULL,  
  `superadmin_id` int(11) NOT NULL DEFAULT '0',
  `reseller_id` int(11) NOT NULL DEFAULT '0',
  `admin_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  FOREIGN KEY (`superadmin_id`) REFERENCES account(`id`),
  FOREIGN KEY (`reseller_id`) REFERENCES account(`id`),
  FOREIGN KEY (`admin_id`) REFERENCES account(`id`)
) 

我想找到带有超级管理员、经销商、管理员名称的手机。问题是我不能在同一个 ID 上多次加入。我试过的查询

select phone,superadmin_id,reseller_id, admin_id, name from reseller_did join 
account on account.id=reseller_did.admin_id 

上面的查询通过加入 admin_id 来显示管理员名称,但是如何获取同一部手机的超级管理员名称和经销商名称?

编辑:示例输入

帐户表

id     name

3      SuperAdmin1
9      Reseller1
10     Admin1

reseller_did

id  phone        superadmin_id   reseller_id   admin_id

1   9090909090   3                 9             10

样本输出

phone        superadmin    reseller    admin

9090909090   SuperAdmin1  Reseller1   Admin1

【问题讨论】:

标签: mysql join foreign-keys primary-key multiple-join-rows


【解决方案1】:

试试这个;)

select r.phone, a.name as admin, re.name reseller, s.name as superadmin
from reseller_did r
join account a on a.id = r.admin_id
join account s on s.id = r.superadmin_id
join account re on re.id = r.reseller_id

SqlFiddle Result

或者

SELECT r.phone,
       MAX(CASE WHEN a.id = r.admin_id THEN a.name END) as admin,
       MAX(CASE WHEN a.id = r.reseller_id THEN a.name END) as reseller,
       MAX(CASE WHEN a.id = r.superadmin_id THEN a.name END) as superadmin
FROM reseller_did r
INNER JOIN account a 
ON a.id IN (r.admin_id, r.superadmin_id, r.reseller_id)
GROUP BY r.phone

这个sql应该感谢@sagi这个问题Get multiple values from another table by different relations

SqlFiddle Result

【讨论】:

    【解决方案2】:

    希望这可行

    select 
        rd.phone as Phone ,
        a.name as Superadmin,
        a1.name as Reseller,
        account.name as Admin
    from
        reseller_did rd
            join
        account ON account.id = rd.admin_id
            join
        account a ON a.id = rd.superadmin_id
            join
        account a1 ON a1.id = rd.reseller_id
    

    【讨论】:

      【解决方案3】:

      您可以为account 表创建三个别名,并使用reseller_did 表将它们INNER JOIN

      SELECT 
      R.id,
      R.phone,
      A1.name AS superadmin,
      A2.name AS reseller,
      A3.name AS admin
      FROM reseller_did R
      INNER JOIN account A1 ON R.superadmin_id = A1.id 
      INNER JOIN account A2 ON R.reseller_id = A2.id
      INNER JOIN account A3 ON R.admin_id = A3.id ;
      

      SQL FIDDLE DEMO 1

      替代方式:

      如果您不想采用 INNER JOIN,可以使用以下查询获得相同的结果。

      SELECT 
      R.phone,
      (SELECT name FROM account WHERE id = R.superadmin_id) AS SuperAdmin,
      (SELECT name FROM account WHERE id = R.reseller_id) AS Reseller,
      (SELECT name FROM account WHERE id = R.admin_id) AS Admin
      FROM reseller_did R;
      

      SQL FIDDLE DEMO 2

      注意:您将电话号码存储在 INT 数据类型中。您不应该使用INT 来存储电话号码。相反,您应该使用VARCHAR

      【讨论】: