SQL在单个列中获取列数据

时间:2016-11-16 08:24:50

标签: sql sql-server

我有一张表,其中保存了员工打孔。对于每个员工的每个日期,表中的列为Punch1,Punch2为Punch10。

enter image description here

我希望所有这些Punch Columns数据都在单列​​中。例如如果连续我有日期存储在Punch1,Punch2,Punch3,Punc4 ....等等。我希望所有这些数据都在一个列中。

如何实现这一目标?

3 个答案:

答案 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 articlethe SO question "Row concatenation with FOR XML, but with multiple columns?"

"垂直" (表)连接:

从视觉上讲,如果要垂直堆叠单个列Punch1Punch2等,那么您将使用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的内容。

例如,不是有几个名为Punch1Punch2等的列(其中每个列包含相同类型的数据),而是只有两列:一列包含{{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列可帮助您找到每个员工的打卡号码的打卡日期