繁体   English   中英

如果列不为空,则基于多行的 Select 语句

[英]Select statement with multiple rows based if columns are not null

我有一个 select 语句,它选择某些列( contact1_namecontact2_namecontact3_name )可以为空的记录。 如果列不为空,我希望它显示为新行。

目前我有:

select
    table_1.id, table_1.fname, table_1.lname, table2.room,
    table_3.contact1,
    table_3.contact2,
    table_3.contact3,
FROM
    table_1
left join table_2
    on table_1.room = table_2.id
left join table_3
    on table_3.cid = table_1.id
where 
    table_1.location = 1
and 
    table_1.room in (1,2,3,4,5,6,7,8,9,10,11)

这将导致这样的事情:

id  |  fname | lname | room | contact1 | contact2 | contact3
 1  |  John  | Smith | r_1  |  Bill    |  George  |
 2  |  Gerry | Name  | r_2  |  Harry   |          | 
 3  |  Will  | Gates | r_2  |  Steve   |  Hannah  |  Stacy
 4  |  Peter | Pall  | r_3  |          |          |      

相反,如果contact1contact2contact3不为null ,我希望它出现在新行中:

id  |  fname | lname | room | contact  
 1  |  John  | Smith | r_1  |  Bill    
 1  |  John  | Smith | r_1  |  George  
 2  |  Gerry | Name  | r_2  |  Harry   
 3  |  Will  | Gates | r_2  |  Steve   
 3  |  Will  | Gates | r_2  |  hannah  
 3  |  Will  | Gates | r_2  |  Stacy

这可能吗? 先感谢您。

是的,您需要使用条件。


select
    table_1.id, table_1.fname, table_1.lname, table2.room,
    CASE
       WHEN table3.contact1 is not null THEN table3.contact1
       WHEN table3.contact2 is not null THEN table3.contact2
       WHEN table3.contact3 is not null THEN table3.contact3
       ELSE null
    END as contact
FROM
    table_1
left join table_2
    on table_1.room = table_2.id
left join table_3
    on table_3.cid = table_1.id
where 
    table_1.location = 1
and 
    table_1.room in (1,2,3,4,5,6,7,8,9,10,11)

更新:这只会选择不为空的联系人。 如果要在新行中获取所有非空联系人,请执行以下操作:

SELECT * FROM (select table_1.id, table_1.fname, table_1.lname, table2.room,
CASE
       WHEN id_rank = 1 THEN contact1
       WHEN id_rank = 2 THEN contact2
       WHEN id_rank = 3 THEN contact3
    END as contact

FROM 

(
select
    table_1.id, table_1.fname, table_1.lname, table2.room,
    table_3.contact1, table3.contact2, table_3.contact3, dense_rank() over ( partition by table3.id order by table_1.id asc ) 
       as "id_order"
FROM
    table_3 left join 
    table_1 on table_3.cid = table_1.id
left join table_2
    on table_1.room = table_2.id

where 
    table_1.location = 1
and 
    table_1.room in (1,2,3,4,5,6,7,8,9,10,11)
) as sub_query

)
  as main_query

WHERE contact is NOT NULL;

这是一种方法:

select
    table_1.id
    , table_1.fname
    , table_1.lname
    , table2.room
    , t3.contact
FROM  table_1
left join table_2  on table_1.room = table_2.id
left join 
(
  select cid, contact1 as contact from table3
  union all 
  select cid, contact2 from table3
  union all 
  select cid, contact3 from table3
) t3 on t3.cid = table_1.id
where table_1.location = 1
  and table_1.room in (1,2,3,4,5,6,7,8,9,10,11)

由于示例表中只有三个联系人列所以我使用联合而不是 PIVOT 表或任何其他替代方案。

SELECT t.id, t.fname, t.lname, t.room, t.contact
FROM ( SELECT id, fname, lname, room, contact1 contact, 1 con_seq
       FROM table_name
       WHERE contact1 IS NOT NULL

       UNION ALL

       SELECT id, fname, lname, room, contact2 contact, 2 con_seq
       FROM table_name
       WHERE contact2 IS NOT NULL

       UNION ALL

       SELECT id, fname, lname, room, contact3 contact, 3 con_seq
       FROM table_name
       WHERE contact3 IS NOT NULL ) t
ORDER BY t.id, t.con_seq; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM