【问题标题】:How can I combine several rows into one using SQL Server如何使用 SQL Server 将多行合并为一行
【发布时间】:2018-04-22 21:12:27
【问题描述】:

我有一个看起来像这样的桌拳

EMP_ID    INpunchDATETIME     OUTpunchDATETIME
-----------------------------------------------
1         2017-11-10 11:59    2017-11-10 13:30
1         2017-11-10 9:00     2017-11-10 10:30

我需要从上一个表中创建一个表 @temptable,如下所示

Emp_ID InPunch1         InPunch2          OUTpunch1         OUTpunch2 
----------------------------------------------------------------------------
1      2017-11-10 9:00  2017-11-10 11:59  2017-11-10 10:30  2017-11-10 13:30

我正在尝试使用 PIVOT,但如果错了我可以更改

DECLARE @temptable Table (
        EMP_ID int,
        InPunch1 datetime,
        InPunch2 datetime,
        OutPunch1 datetime,
        OutPunch2 datetime);

SELECT
    Emp_ID, InPunch1, InPunch2, Outpunch1, Outpunch2
INTO
    @temptable
FROM 
    (SELECT
         EMP_ID, INPunchDATETIME, OUTpunchDATETIME
     FROM 
         punches) AS p
PIVOT
    (

这就是我所知道的。

【问题讨论】:

  • 我假设出拳次数是无限的?
  • 我不确定 PIVOT 是您要找的东西:technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
  • 这样的事情可能会起作用:选择前 1 个 p.Emp_ID,p2.InPunch 作为 Inpunch1,p.InPunch 作为 inpunch2,p2.Outpunch 作为 outpunch1,p.Outpunch 作为 outpunch2 FROM testing p INNER JOIN testing p2 ON p.EMP_ID = p2.EMP_ID AND p.INpunch p2.INpunch AND DAY(p.INpunch ) = DAY(p2.INpunch)
  • 但是,您在 temptable 声明中有语法错误,需要充实问题描述,例如我假设这是试图跟踪拆分班次,但是,没有提到确保在同一天发生打卡/打卡等。
  • 我试图让问题更通用,以便对其他人更有帮助。是的,我计划添加一些逻辑以确保所有的拳都发生在同一天。此外,我已经将数据保存在一个数据库中,需要发送到另一个数据库。发送数据库的格式类似于我的第一个示例,接收数据库的格式类似于第二个。

标签: tsql pivot sql-server-2014


【解决方案1】:

示例数据设置

create table dbo.punches
    (
        emp_id int
        , INpunchDATETIME datetime
        , OUTpunchDATETIME datetime
    )

insert into dbo.punches
values (1, '2017-11-10 11:59','2017-11-10 13:30')
    , (1, '2017-11-10 9:00','2017-11-10 10:30')

回答

打孔表在两个单独的列中包含输入/输出打孔,最里面的查询将两种类型的打孔移动到一列中,以允许所有数据一次被pivoted。下一个查询将它们按时间顺序排列,并在 punch_ind 中创建值,这将是最终的列名。最后一步是pivot数据并选择最终输出。

select post.emp_id
, post.InPunch1
, post.InPunch2
, post.OutPunch1
, post.OutPunch2
from (
    --decide which punch is in1/in2/etc.
    select sub.emp_id
    , sub.punch_type + 'Punch' + cast(row_number() over (partition by sub.emp_id, sub.punch_type order by sub.punch_ts) as varchar(10)) as punch_ind --punch indicator
    , sub.punch_ts
    from (
        --get all of the data in one column to enable pivot
        select p.emp_id
        , 'In' as punch_type
        , p.INpunchDATETIME as punch_ts
        from dbo.punches as p
        union all
        select p.emp_id
        , 'Out' as punch_type
        , p.OUTpunchDATETIME as punch_ts
        from dbo.punches as p
        ) as sub
    ) as pre --before the pivot
pivot (max(pre.punch_ts) for pre.punch_ind in ([InPunch1], [InPunch2], [OutPunch1], [OutPunch2])) as post --after the pivot

只需将此最终输出和insert 记录放入您选择的临时表/表变量中。

【讨论】:

  • 是的!这完美无缺。我只有一个问题。我正在尝试添加逻辑以仅选择昨天的拳头。我添加了 Where InPunchDateTime >= DATEADD(day, -1, convert(date, GETDATE())) 和 InPunchDateTime
  • 你救了我的命!
  • 很高兴能帮上忙!
猜你喜欢
  • 2011-12-21
  • 2012-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 2021-08-19
  • 2016-03-27
  • 2017-09-24
相关资源
最近更新 更多