CASE WHEN提供2行重复ID

时间:2017-10-24 05:52:34

标签: sql oracle

我编写了一个查询,它将产生如下结果。

select t1.id as id,
CASE
    WHEN t3.key_id is not null and t3.key_id='SILICA'
    THEN t3.id
    END as SILICA_ID,
CASE
    WHEN t3.key_id is not null and t3.key_id='Mutual'
    THEN t3.id
    END as Mutual_ID
from table1 t1, table2 t2, table3 t3 
where t1.id=t2.t1_id and t2.id=t3.t2_id and t3.key_id in ('SILICA','Mutual') 
order by t1.id;
id     SILICA_ID      Mutual_id
==     =========      =========
1      null           1234
1      3456           null
2      null           7890
2      2374           null
2      4587           null
2      null           3489

但是,我需要一个如下结果。

id     SILICA_ID      Mutual_id
==     =========      =========
1      3456           1234
2      2345           7890
2      4587           3489

我怎样才能做到这一点?

提前致谢

3 个答案:

答案 0 :(得分:2)

您需要一个聚合解决方案,例如

select id
       , max(silica_id) as silica_id
       , max(Mutual_ID) as Mutual_ID
from (
    select t1.id as id,
    CASE
        WHEN t3.key_id is not null and t3.key_id='SILICA'
        THEN t3.id
        END as SILICA_ID,
    CASE
        WHEN t3.key_id is not null and t3.key_id='Mutual'
        THEN t3.id
        END as Mutual_ID
    from table t1, table t2, table t3 
    where t1.id=t2.t1_id and t2.id=t3.t2_id and t3.key_id in ('SILICA','Mutual')
    ) 
group by id
order by id;

答案 1 :(得分:1)

您可以使用pivot语法:

select *
from   (
      select     t1.id, 
                 t3.id as t3_id, 
                 t3.key_id
      from       tabl t1
      inner join tabl t2 on t1.id = t2.t1_id
      inner join tabl t3 on t2.id = t3.t2_id
      where      t3.key_id in ('SILICA', 'Mutual')
) pivot (
      max(t3_id)
      for key_id in ('SILICA' as silica_id, 'Mutual' as mutual_id)
);

注意:使用join子句表达连接条件是一个好习惯,而不是将它们放在where子句中。

答案 2 :(得分:1)

t2 t1t3,每t2 t1.id t3.id。但是每个t1.id需要一个结果行。所以你想汇总你的数据。

您的结果只显示t3.key_id t1.idt1.id一个select t1.id as id, max(case when t3.key_id = 'SILICA' THEN t3.id end) as silica_id, max(case when t3.key_id = 'Mutual' then t3.id end) as mutual_id from t1 join t2 on t2.t1_id = t1.id join t3 on t3.t2_id = t2.id and t3.key_id in ('SILICA','Mutual') group by t1.id order by t1.id; 。这是意料之外的,表明错误的数据模型或不完整的样本数据。

无论如何,为了按select t1_id, s.t3_id as silica_id, m.t3_id as mutual_id t1.id as t1_id, t3.id as t3_id ( select distinct t1.id as t1_id, t3.id as t3_id, row_number() over (partition by t1.id order by t3.id) as rn from t1 join t2 on t2.t1_id = t1.id join t3 on t3.t2_id = t2.id and t3.key_id = 'SILICA' ) s full outer join ( select distinct t1.id as t1_id, t3.id as t3_id, row_number() over (partition by t1.id order by t3.id) as rn from t1 join t2 on t2.t1_id = t1.id join t3 on t3.t2_id = t2.id and t3.key_id = 'Mutual' ) m using (t1_id, rn); SELECT Outlet.Code, COUNT(DISTINCT (LogDate)) AS [Worked Days], AccessLog.EmployeeID AS [Employee ID], abr AS Outlet, GEmp.Name, Outlet.Brands FROM [dbo].[AccessLog] INNER JOIN dbo.Outlet ON dbo.Outlet.Code = dbo.AccessLog.TerminalID INNER JOIN dbo.GEmp ON dbo.GEmp.EmpCode = dbo.AccessLog.EmployeeID WHERE CONVERT(datetime, [LogDate]) BETWEEN '2017/10/01' AND '2017/10/31' AND Outlet.Brands = 'brand1' AND [dbo].[AccessLog].InOut = '0' GROUP BY AccessLog.EmployeeID, dbo.Outlet.abr, GEmp.Name, dbo.Outlet.Brands, dbo.Outlet.Malls, Outlet.Code ORDER BY Outlet.Malls, GEmp.Name 聚合获得一个结果行并使用条件聚合:

Code    Worked Days Employee ID Outlet  Name    Brands
-------------------------------------------------------
20019   16          362573      shop1   john    brand1
20038    3          362573      shop2   john    brand1
20038    5          362574      shop1   mike    brand1
20038    1          362574      shop2   mike    brand1

更新:您更改的请求会显示结果行,其中SILICA / Mutual对似乎没有直接关联。看起来你更愿意以类似报纸的方式列出它们。你可以选择' SILICA'和' Mutual'分开,给他们行号并加入这些。

Code    Worked Days Employee ID Outlet  Name    Brands
---------------------------------------------------------
20019   16          362573      shop1   john    brand1
20038    5          362574      shop1   mike    brand1