我有一张桌子:
CREATE TABLE [PersonelTraffic](
[CardNo] [int] ,
[CardDateTime] [smalldatetime] )
和行为:
CardNo CardDateTime
1048 2014-06-02 16:30:00
1414 2014-06-02 13:11:00
1414 2014-06-02 13:59:00
1414 2014-06-02 16:43:00
如何选择按天显示一行的时间:
CardNo Date Time0 Time1 Time2 Time3
1414 2014-06-02 13:11 13:59 16:43 Null
1048 2014-06-02 16:30 Null Null Null
使用Pivot运算符或任何其他解决方案。
答案 0 :(得分:1)
MayBe像这样的东西
;with cte as
(
SELECT CardNo,CardDateTime,Cast(CardDateTime As Date)AS Date,Row_Number() over(Partition By CARDNO Order By CARDNO) AS RN
FROM personeltraffic
)
SELECT CardNo,Date,
MAX(CASE WHEN RN = 1 Then Convert(char(5), CardDateTime, 108) ELSE NULL End)AS Time1,
MAX(CASE WHEN RN = 2 Then Convert(char(5), CardDateTime, 108) ELSE NULL End)AS Time2,
MAX(CASE WHEN RN = 3 Then Convert(char(5), CardDateTime, 108) ELSE NULL End)AS Time3,
MAX(CASE WHEN RN = 4 Then Convert(char(5), CardDateTime, 108) ELSE NULL End)AS Time4
From cte
Group By CardNo,Date
<强>输出:强>
+--------+------------+---------+---------+---------+--------+
| CardNo | Date | Time0 | Time1 | Time2 | Time3 |
+--------+------------+---------+---------+---------+--------+
| 1414 | 2014-06-02 | 13:11 | 13:59 | 16:43 | Null |
| 1048 | 2014-06-02 | 16:30 | Null | Null | Null |
+--------+------------+---------+---------+---------+--------+
答案 1 :(得分:0)
您可以这样做:
;with cte as
(select cardno, convert(time,carddatetime) cardtime, row_number() over (partition by cardno order by carddatetime) rn
from personeltraffic)
select distinct p.cardno [CardNo],
convert(date,p.carddatetime) [Date],
c1.cardtime [Time0],
c2.cardtime [Time1],
c3.cardtime [Time2],
c4.cardtime [Time3]
from personeltraffic p
left join cte c1 on p.cardno = c1.cardno and c1.rn = 1
left join cte c2 on p.cardno = c2.cardno and c2.rn = 2
left join cte c3 on p.cardno = c3.cardno and c3.rn = 3
left join cte c4 on p.cardno = c4.cardno and c4.rn = 4
order by p.cardno
基本上,您使用row_number()
为一天内的每个时间分配一个序列号,然后多次连接以获得序列中特定数字的时间。但是,考虑到此查询中的连接数,我建议您出于性能原因寻找替代方案。
答案 2 :(得分:0)
除Vignesh Kumar的答案外,基于PIVOT的答案基本上使用相同的执行计划:
SELECT
CardNo,
[Date],
CONVERT(CHAR(5), [1], 108) AS [Time0],
CONVERT(CHAR(5), [2], 108) AS [Time1],
CONVERT(CHAR(5), [3], 108) AS [Time2],
CONVERT(CHAR(5), [4], 108) AS [Time3]
FROM (
SELECT
CardNo,
CONVERT(DATE, CardDateTime) AS [Date],
CardDateTime,
ROW_NUMBER() OVER (PARTITION BY CardNo ORDER BY CardDateTime) AS TimeOrdinal
FROM
PersonelTraffic
) pt
PIVOT (
MAX(CardDateTime) FOR [TimeOrdinal] IN (
[1],
[2],
[3],
[4]
)
) pvt