具有多行输出的 SQL Server 数据透视

发布于 2025-01-14 05:07:43 字数 3053 浏览 1 评论 0原文

我的表中有以下数据。

输入图片此处描述

我需要以下格式的输出。

输入图片这里的描述

我尝试过旋转,但似乎无法解决它。 有人可以在这里指导我吗?

提前致谢。

编辑: 文本格式的数据。

员工ID轮班代码出勤日期输入日期超时日期时间加班时间
26ShiftCC101-03-202201-03-2022 09:1001-03-2022 18:101
26ShiftCC102-03-202202-03-2022 09:1502-03-2022 18:152
26ShiftCC103-03-202203-03-2022 09:0503-03-2022 18:052
26ShiftCC104-03-202204-03-2022 09:1004-03-2022 18:101
26ShiftCC105-03-202205-03-2022 09:1305-03-2022 18:132
26ShiftCC106-03-202206-03-2022 09:1406-03-2022 18:143
26ShiftCC107-03-202207-03-2022 09:1607-03-2022 18:162
26ShiftCC108-03-202208-03-2022 09:3008-03-2022 18:301
26ShiftCC109-03-202209-03-2022 09:2009-03-2022 18:202
26ShiftCC110-03-202210-03-2022 09:2510-03-2022 18:253

以文本格式输出:

EmployeeIDShiftCodeDataType01-03-202202-03-202203-03-202204-03-202205-03-202206-03-202207-03 -2022年08-03-202209-03-202210-03-2022
26ShiftCC1InDateTime01-03-2022 09:1002-03-2022 09:1503-03-2022 09:0504-03-2022 09:1005-03-2022 09:1306-03-2022 09:1407-03-2022 09:1608-03-2022 09:3009-03-2022 09:2010-03-2022 09:25
26ShiftCC1过时时间01-03-2022 18:1002-03-2022 18:1503-03-2022 18:0504-03-2022 18:1005-03-2022 18:1306-03-2022 18:1407- 03-2022 18:1608-03-2022 18:3009-03-2022 18:2010-03-2022 18:25
26ShiftCC1加班时间1221232123

I have the following data in a Table.

enter image description here

And i need output in below format.

enter image description here

I tried pivoting but seems like not able to resolve it.
Can someone please guide me here?

Thanks in advance.

Edit:
Data in Text Format.

EmployeeIDShiftCodeAttendanceDateinDateTimeoutDateTimeOverTimeHours
26ShiftCC101-03-202201-03-2022 09:1001-03-2022 18:101
26ShiftCC102-03-202202-03-2022 09:1502-03-2022 18:152
26ShiftCC103-03-202203-03-2022 09:0503-03-2022 18:052
26ShiftCC104-03-202204-03-2022 09:1004-03-2022 18:101
26ShiftCC105-03-202205-03-2022 09:1305-03-2022 18:132
26ShiftCC106-03-202206-03-2022 09:1406-03-2022 18:143
26ShiftCC107-03-202207-03-2022 09:1607-03-2022 18:162
26ShiftCC108-03-202208-03-2022 09:3008-03-2022 18:301
26ShiftCC109-03-202209-03-2022 09:2009-03-2022 18:202
26ShiftCC110-03-202210-03-2022 09:2510-03-2022 18:253

output in Text Format:

EmployeeIDShiftCodeDataType01-03-202202-03-202203-03-202204-03-202205-03-202206-03-202207-03-202208-03-202209-03-202210-03-2022
26ShiftCC1InDateTime01-03-2022 09:1002-03-2022 09:1503-03-2022 09:0504-03-2022 09:1005-03-2022 09:1306-03-2022 09:1407-03-2022 09:1608-03-2022 09:3009-03-2022 09:2010-03-2022 09:25
26ShiftCC1OutDateTime01-03-2022 18:1002-03-2022 18:1503-03-2022 18:0504-03-2022 18:1005-03-2022 18:1306-03-2022 18:1407-03-2022 18:1608-03-2022 18:3009-03-2022 18:2010-03-2022 18:25
26ShiftCC1OverTimeHours1221232123

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我纯我任性 2025-01-21 05:07:43

首先,您的数据集无法获得您想要的准确输出。您要么需要放弃加班列,因为在旋转这些列后会自动转换为日期类型,要么您可以更改列的数据类型(我为此使用了视图)。

另外,我假设您的“AttendanceDate”是动态的,所以我使用了动态解决方案。

我在这里使用了 @Taryn 的解决方案:

选项 1:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.att_date) 
            FROM test1 c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_entry
                from test1
           ) x
            pivot 
            (
                 max(att_entry)
                for att_date in (' + @cols + ')
            ) p 
            union 
            SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_out
                from test1
           ) x
            pivot 
            (
                 max(att_out)
                for att_date in (' + @cols + ')
            ) p '

execute(@query)

输入图像描述这里

DBFiddle_Option1:

Option2:

您可以创建视图这样可以绕过列不兼容。

create view test2
as select idx, name as name, convert(varchar, att_date) as att_date,
convert(varchar, att_entry) as att_entry,
convert(varchar, att_out) as att_out,
convert(varchar, overtime) as overtime
from test1;

然后你可以使用这个:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.att_date) 
            FROM test2 c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    overtime
                from test2
           ) x
            pivot 
            (
                 max(overtime)
                for att_date in (' + @cols + ')
            ) p 
            union 
            SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_out
                from test2
           ) x
            pivot 
            (
                 max(att_out)
                for att_date in (' + @cols + ')
            ) p 
            union 
            SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_entry
                from test2
           ) x
            pivot 
            (
                 max(att_entry)
                for att_date in (' + @cols + ')
            ) p order by 3 desc'

execute(@query)

在此处输入图像描述

DBFiddle_Option2:

注意:不将数据转换为字符串,最后看起来像这样:

在此处输入图像描述

First of all, you can' t have the exactly output you want with your dataset. Either you need to give up your overtime column because after pivotting those columns automatically convert to date type or you could change datatype of your columns(I used view for that).

Also, I assumed your "AttendanceDate" is dynamic, so I used a dynamic solution.

I used @Taryn' s solution here:

Option 1:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.att_date) 
            FROM test1 c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_entry
                from test1
           ) x
            pivot 
            (
                 max(att_entry)
                for att_date in (' + @cols + ')
            ) p 
            union 
            SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_out
                from test1
           ) x
            pivot 
            (
                 max(att_out)
                for att_date in (' + @cols + ')
            ) p '

execute(@query)

enter image description here

DBFiddle_Option1:

or

Option2:

You can create a view like this to bypass column incompatibility.

create view test2
as select idx, name as name, convert(varchar, att_date) as att_date,
convert(varchar, att_entry) as att_entry,
convert(varchar, att_out) as att_out,
convert(varchar, overtime) as overtime
from test1;

Then you can use this:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.att_date) 
            FROM test2 c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    overtime
                from test2
           ) x
            pivot 
            (
                 max(overtime)
                for att_date in (' + @cols + ')
            ) p 
            union 
            SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_out
                from test2
           ) x
            pivot 
            (
                 max(att_out)
                for att_date in (' + @cols + ')
            ) p 
            union 
            SELECT idx, name, ' + @cols + ' from 
            (
                select idx,
                       name,
                    att_date,
                    att_entry
                from test2
           ) x
            pivot 
            (
                 max(att_entry)
                for att_date in (' + @cols + ')
            ) p order by 3 desc'

execute(@query)

enter image description here

DBFiddle_Option2:

Note: without converting data to string it looks like this at the end:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文