sql - 如何将数据分成两列

标签 sql sql-server t-sql sql-server-2008-r2

考虑以下表结构和示例数据 -

EmpID InputDateTime      StatusINOUT
-------------------------------------
1     2018-05-26 08:44     1
1     2018-05-26 08:44     2
2     2018-05-28 08:44     1
2     2018-05-28 12:44     2                   
1     2018-05-21 08:44     1
1     2018-05-21 10:44     2
2     2018-05-23 08:44     1
2     2018-05-23 08:44     2   

现在我想分隔列InputDateTime分为两列,即 INTIME(1)OUTTIME(2) 。这背后的逻辑是 StatusInOut 的日期为 1 将是 InTimeStatusInOut为 2 时日期值为 OUTTIME(2) .

预期的输出格式如下所示:

Empid   INTIME(1)          OUTIME(2)
--------------------------------------------
1      2018-05-26 08:44    2018-05-26 08:44
2      2018-05-28 08:44    2018-05-28 12:44
1      2018-05-21 08:44    2018-05-21 10:44
2      2018-05-23 08:44    2018-05-23 08:44

这是我迄今为止尝试过的

create table #tempStatus (EmpId int, intTime datetime, sStatus int)    
insert into #tempStatus    
values(1, '2018-05-26 08:44', 1),    
    (1, '2018-05-26 08:44', 2),    
    (2, '2018-05-28 08:44', 1),    
    (2, '2018-05-28 12:44', 2),        
    (1, '2018-05-21 08:44', 1),    
    (1, '2018-05-21 10:44', 2),        
    (2, '2018-05-23 08:44', 1),    
    (2, '2018-05-23 08:44', 2)    

select EmpId, MIN(intTime) as intTime, MIN(intTime) as OutTime into #tempA from (  
select EmpId, intTime, intTime as OutTime  
from #tempStatus where sStatus = 1  
)a   
group by EmpId, intTime  

select EmpId, MAX(outTime) as outTime into #tempB from(   
select EmpId, intTime as outTime  
from #tempStatus where sStatus = 2  
)b   
group by empId,outTime     

select * from #tempA order by EmpId  

drop table #tempA  
drop table #tempB  
DROP TABLE #tempStatus

最佳答案

您需要row_number()并使用它们的差异来进行条件聚合,这也称为间隙和岛屿问题:

select empid, 
       max(case when sStatus = 1 then intTime end) as INTIME,
       max(case when sStatus = 2 then intTime end) as OUTIME
from (select t.*, 
             row_number () over ( order by inttime) as seq1,
             row_number () over (partition by empid order by inttime) as seq2
      from #tempStatus t
     ) t
group by empid, (seq1-seq2);

编辑:如果您想在 InTime 不存在时显示 OutTime,那么您可以使用子查询:

select t.empid, 
       coalesce(INTIME, OUTIME) as INTIME,
       coalesce(OUTIME, INTIME) as OUTIME
from ( <query here> 
     ) t;

关于sql - 如何将数据分成两列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53832254/

相关文章:

java - querydsl - 列表条件

javascript - PHP数组未将多行插入数据库

sql-server - SSIS OLEDB 连接管理器 - 无法连接到数据库(未显示数据库名称)

T-SQL:当空时从备用表中选择列

SQL 查询以获取活跃客户列表。活跃的是那些每周至少出现一次的表

sql - 如何删除表中没有FK关系的所有行

sql - 按引用字段的相对增量 ID

sql - postgres sql 'cast a tuple' 习语记录在哪里?

sql - 从 SQL Server 表中检索每个类别的不同行数

sql-server - 连接之间巨大的性能差异