SQL 具有多行输出的服务器数据透视表
SQL Server Pivot with Multiple Rows Output
我在 Table 中有以下数据。
我需要以下格式的输出。
我试过旋转但似乎无法解决它。
有人可以在这里指导我吗?
提前致谢。
编辑:
文本格式的数据。
EmployeeID
ShiftCode
AttendanceDate
inDateTime
outDateTime
OverTimeHours
26
ShiftCC1
01-03-2022
01-03-2022 09:10
01-03-2022 18:10
1
26
ShiftCC1
02-03-2022
02-03-2022 09:15
02-03-2022 18:15
2
26
ShiftCC1
03-03-2022
03-03-2022 09:05
03-03-2022 18:05
2
26
ShiftCC1
04-03-2022
04-03-2022 09:10
04-03-2022 18:10
1
26
ShiftCC1
05-03-2022
05-03-2022 09:13
05-03-2022 18:13
2
26
ShiftCC1
06-03-2022
06-03-2022 09:14
06-03-2022 18:14
3
26
ShiftCC1
07-03-2022
07-03-2022 09:16
07-03-2022 18:16
2
26
ShiftCC1
08-03-2022
08-03-2022 09:30
08-03-2022 18:30
1
26
ShiftCC1
09-03-2022
09-03-2022 09:20
09-03-2022 18:20
2
26
ShiftCC1
10-03-2022
10-03-2022 09:25
10-03-2022 18:25
3
以文本格式输出:
EmployeeID
ShiftCode
DataType
01-03-2022
02-03-2022
03-03-2022
04-03-2022
05-03-2022
06-03-2022
07-03-2022
08-03-2022
09-03-2022
10-03-2022
26
ShiftCC1
InDateTime
01-03-2022 09:10
02-03-2022 09:15
03-03-2022 09:05
04-03-2022 09:10
05-03-2022 09:13
06-03-2022 09:14
07-03-2022 09:16
08-03-2022 09:30
09-03-2022 09:20
10-03-2022 09:25
26
ShiftCC1
OutDateTime
01-03-2022 18:10
02-03-2022 18:15
03-03-2022 18:05
04-03-2022 18:10
05-03-2022 18:13
06-03-2022 18:14
07-03-2022 18:16
08-03-2022 18:30
09-03-2022 18:20
10-03-2022 18:25
26
ShiftCC1
OverTimeHours
1
2
2
1
2
3
2
1
2
3
首先,您的数据集无法得到您想要的准确输出。您需要放弃加班列,因为在旋转这些列后会自动转换为日期类型,或者您可以更改列的数据类型(我为此使用了视图)。
此外,我假设您的“AttendanceDate”是动态的,所以我使用了动态解决方案。
I used @Taryn' s solution here:
选项 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)
或
选项2:
您可以创建这样的视图来绕过列不兼容问题。
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)
注意:如果不将数据转换为字符串,最后看起来像这样:
我在 Table 中有以下数据。
我需要以下格式的输出。
我试过旋转但似乎无法解决它。 有人可以在这里指导我吗?
提前致谢。
编辑: 文本格式的数据。
EmployeeID | ShiftCode | AttendanceDate | inDateTime | outDateTime | OverTimeHours |
---|---|---|---|---|---|
26 | ShiftCC1 | 01-03-2022 | 01-03-2022 09:10 | 01-03-2022 18:10 | 1 |
26 | ShiftCC1 | 02-03-2022 | 02-03-2022 09:15 | 02-03-2022 18:15 | 2 |
26 | ShiftCC1 | 03-03-2022 | 03-03-2022 09:05 | 03-03-2022 18:05 | 2 |
26 | ShiftCC1 | 04-03-2022 | 04-03-2022 09:10 | 04-03-2022 18:10 | 1 |
26 | ShiftCC1 | 05-03-2022 | 05-03-2022 09:13 | 05-03-2022 18:13 | 2 |
26 | ShiftCC1 | 06-03-2022 | 06-03-2022 09:14 | 06-03-2022 18:14 | 3 |
26 | ShiftCC1 | 07-03-2022 | 07-03-2022 09:16 | 07-03-2022 18:16 | 2 |
26 | ShiftCC1 | 08-03-2022 | 08-03-2022 09:30 | 08-03-2022 18:30 | 1 |
26 | ShiftCC1 | 09-03-2022 | 09-03-2022 09:20 | 09-03-2022 18:20 | 2 |
26 | ShiftCC1 | 10-03-2022 | 10-03-2022 09:25 | 10-03-2022 18:25 | 3 |
以文本格式输出:
EmployeeID | ShiftCode | DataType | 01-03-2022 | 02-03-2022 | 03-03-2022 | 04-03-2022 | 05-03-2022 | 06-03-2022 | 07-03-2022 | 08-03-2022 | 09-03-2022 | 10-03-2022 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
26 | ShiftCC1 | InDateTime | 01-03-2022 09:10 | 02-03-2022 09:15 | 03-03-2022 09:05 | 04-03-2022 09:10 | 05-03-2022 09:13 | 06-03-2022 09:14 | 07-03-2022 09:16 | 08-03-2022 09:30 | 09-03-2022 09:20 | 10-03-2022 09:25 |
26 | ShiftCC1 | OutDateTime | 01-03-2022 18:10 | 02-03-2022 18:15 | 03-03-2022 18:05 | 04-03-2022 18:10 | 05-03-2022 18:13 | 06-03-2022 18:14 | 07-03-2022 18:16 | 08-03-2022 18:30 | 09-03-2022 18:20 | 10-03-2022 18:25 |
26 | ShiftCC1 | OverTimeHours | 1 | 2 | 2 | 1 | 2 | 3 | 2 | 1 | 2 | 3 |
首先,您的数据集无法得到您想要的准确输出。您需要放弃加班列,因为在旋转这些列后会自动转换为日期类型,或者您可以更改列的数据类型(我为此使用了视图)。
此外,我假设您的“AttendanceDate”是动态的,所以我使用了动态解决方案。
I used @Taryn' s solution here:
选项 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)
或
选项2:
您可以创建这样的视图来绕过列不兼容问题。
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)
注意:如果不将数据转换为字符串,最后看起来像这样: