我有一张表,其中保存了员工打孔。对于每个员工的每个日期,表中的列为Punch1,Punch2为Punch10。
我希望所有这些Punch Columns数据都在单列中。例如如果连续我有日期存储在Punch1,Punch2,Punch3,Punc4 ....等等。我希望所有这些数据都在一个列中。
如何实现这一目标?
答案 0 :(得分:6)
UNPIVOT
可用于规范化您的表格:
如果您的表名为EmployeePunches
,它将如下所示:
SELECT UserID, Punch
FROM
(
SELECT UserID, Punch1, Punch2, Punch3, Punch4
FROM EmployeePunches
) AS ep
UNPIVOT
(
Punch FOR Punches IN (Punch1, Punch2, Punch3, Punch4)
) AS up
使用UNION ALL
也可以,但每次打印时你会有1个选择语句。
使用UNPIVOT
,您只需要1个语句,只需添加所需的Punch列。
答案 1 :(得分:4)
如果对于每一行,您希望派生一个包含所有时间戳的新列Punches1To10
,例如:以逗号分隔的列表(例如'xxxx-xx-xa, xxxx-xx-xb, xxxx-xx-xc, …'
),然后FOR XML
将是您正在寻找的内容。
有关此问题的教程,请参阅this article和the SO question "Row concatenation with FOR XML, but with multiple columns?"
从视觉上讲,如果要垂直堆叠单个列Punch1
,Punch2
等,那么您将使用UNION ALL
连接几个select语句的结果。对于两列,这将是这样的:
SELECT Punch1 AS Punch FROM YourTable
UNION ALL
SELECT Punch2 AS Punch FROM YourTable
有三列,它将成为:
SELECT Punch1 AS Punch FROM Punches
UNION ALL
SELECT Punch2 AS Punch FROM Punches
UNION ALL
SELECT Punch3 AS Punch FROM Punches;
您可能很快就会失去更多PunchN
列。
因此,我是否可以建议您首先将此表重新设计为更多normalized的内容。
例如,不是有几个名为Punch1
,Punch2
等的列(其中每个列包含相同类型的数据),而是只有两列:一列包含{{1来自1
列名称的{},2
等,另一个包含时间戳:
PunchN
与this answer类似,数据库系统可以通过UNPIVOT
为您执行此类操作。
现在,无论您拥有多少PunchN Date
1 xxxx-xx-xa
1 xxxx-xx-xb
1 xxxx-xx-xc
2 xxxx-xx-xd
2 xxxx-xx-xe
…
列,您的查询就是为"垂直"连接总是一样的:
Punch
("水平"连接也会变得更简单。)
答案 2 :(得分:3)
我认为你正在寻找像这样的东西
select Employee,Punch_date,Identifier
from YourTable
cross apply (values (Punch1,'Punch1'),
(Punch2,'Punch2'),
(Punch3,'Punch3'),
.......
(Punch4,'Punch4')) tc(Punch_date,Identifier)
Identifier
列可帮助您找到每个员工的打卡号码的打卡日期