在相关 table 中合并条件

Coalessing with condition in related table

我在 MySQL 5.7.35 工作,我有以下 tables:

create table Table1 (
    Id int not null auto_increment,
    Name varchar(255) not null,
    primary key(Id)
);

create table Table2 (
    Id int not null auto_increment,
    Name varchar(255) not null,
    Table1_Id int not null,
    primary key(Id),
    foreign key(Table1_Id) references Table1(Id)  
);


create table Table3 (
    Id int not null auto_increment,
    Type varchar(255) not null,
    Name varchar(255) not null,
    Result varchar(255) not null,
    Table2_Id int not null,
    primary key(Id),
    foreign key(Table2_Id) references Table2(Id)
);

在里面,我有以下数据:

| Id  | Name       |
| --- | ---------- |
| 1   | Computer A |

---

| Id  | Name       | Table1_Id |
| --- | ---------- | --------- |
| 1   | Test Run 1 | 1         |

---

| Id  | Type      | Name      | Result  | Table2_Id |
| --- | --------- | --------- | ------- | --------- |
| 1   | Processor | MMX       | Pass    | 1         |
| 2   | Processor | SSE       | Pass    | 1         |
| 3   | Processor | SSE 2     | Pass    | 1         |
| 4   | Display   | Red       | Pass    | 1         |
| 5   | Display   | Green     | Pass    | 1         |
| 6   | Keyboard  | General   | Pass    | 1         |
| 7   | Keyboard  | Lights    | Skipped | 1         |
| 8   | Network   | Ethernet  | Pass    | 1         |
| 9   | Network   | Wireless  | Skipped | 1         |
| 10  | Network   | Bluetooth | Fail    | 1         |

所需查询

我想要两列 table1_nametest_result,其中 test_result 是具有以下逻辑的连接字符串:

对于 Type 中的任何给定值:

因此对于当前数据,输出将是:

| table1_name | test_result                                                      |
| ----------- | ---------------------------------------------------------------- |
| Computer A  | Processor: Pass, Display: Pass, Keyboard: Skipped, Network: Fail |

当前查询

当我希望合并的项目在子 table 两层以下时,我正在努力进行合并。我当前的查询是:

select t1.Name as 'table1_name'
-- coalesce to happen here
from Table1 t1
inner join Table2 t2 on t1.Id = t2.Table1_Id
inner join Table3 t3 on t2.Id = t3.Table2_Id;

我创建了一个 db-fiddle 让事情变得更简单。

这看起来像两个级别的聚合:

select Name, group_concat(name, ': ', result separator ', ')
from (select t1.Name, t3.type,
             (case when min(result) = max(result) then min(result)
                   else 'Skipped'
              end) as result
      from Table1 t1 inner join
           Table2 t2
           on t1.Id = t2.Table1_Id inner join
           Table3 t3
           on t2.Id = t3.Table2_Id
      group by t1.Name, t3.type
     ) nt
group by Name;

使用 GROUP_CONCAT() 以您的首选顺序为每个 NameType 组合收集所有 Result,然后在另一个聚合级别中选择第一个:

SELECT table1_name,
       GROUP_CONCAT(Type, ': ', SUBSTRING_INDEX(Results, ',', 1) SEPARATOR ', ') test_result
FROM (
  SELECT t1.Name table1_name, t3.Type,
         GROUP_CONCAT(Result ORDER BY Result = 'Fail' DESC, Result = 'Skipped' DESC) Results
  FROM Table1 t1
  INNER JOIN Table2 t2 on t1.Id = t2.Table1_Id
  INNER JOIN Table3 t3 on t2.Id = t3.Table2_Id
  GROUP BY t1.Name, t3.Type
) t
GROUP BY table1_name;

如果您想在结果中保留 Type 的顺序:

SELECT table1_name,
       GROUP_CONCAT(Type, ': ', SUBSTRING_INDEX(Results, ',', 1) ORDER BY Id SEPARATOR ', ') test_result
FROM (
  SELECT t1.Name table1_name, MIN(t3.Id) Id, t3.Type,
         GROUP_CONCAT(Result ORDER BY Result = 'Fail' DESC, Result = 'Skipped' DESC) Results
  FROM Table1 t1
  INNER JOIN Table2 t2 on t1.Id = t2.Table1_Id
  INNER JOIN Table3 t3 on t2.Id = t3.Table2_Id
  GROUP BY t1.Name, t3.Type
) t
GROUP BY table1_name;

参见demo