我正在使用MS SQL Server 2008
表名是 tblDateTimeLog :
ID INT(AI)
RecordID INT
DateLog DATE
TimeLog TIME
DetachmentCode INT
EntryDate DATETIME
IsDeleted BIT
UserID VARCHAR(50)
我有一张包含这个的表:
RecordID | DateLog | TimeLog
11 | 2013-06-01 | 07:59:00
11 | 2013-06-01 | 19:01:00
11 | 2013-06-02 | 07:57:00
11 | 2013-06-02 | 19:03:00
11 | 2013-06-03 | 07:49:00
11 | 2013-06-03 | 19:11:00
14 | 2013-06-04 | 08:01:00
14 | 2013-06-04 | 19:03:00
14 | 2013-06-05 | 07:52:00
14 | 2013-06-05 | 19:02:00
一个记录ID可以在同一个DateLog上有多个TimeLog
现在我希望它显示如下:
日期为列和MIN(TimeLog)和MAX(TimeLog)之间的总小时数
RecordID | 2013-06-01 | 2013-06-02 | 2013-06-03 | 2013-06-04 | 2013-06-05
11 | 11:02:00 | 11:06:00 | 11:22:00 | NULL | NULL
14 | NULL | NULL | NULL | 11:02:00 | 11:10:00
根据Mikael的答案,这有效,但据我了解他的查询,这会返回MIN(TimeLog):
DECLARE @SQL NVARCHAR(MAX)
DECLARE @ColumnList NVARCHAR(MAX)
SELECT @ColumnList =
STUFF
(
(
SELECT DISTINCT ','+QUOTENAME(DateLog)
FROM TESTPIS.dbo.tblDateTimeLog
WHERE IsDeleted=0 AND DateLog >= '2013-06-15' AND DateLog <= '2013-06-30'
ORDER BY 1
FOR XML PATH('')
), 1, 1, ''
)
SET @SQL = 'SELECT P.RecordID, '+@ColumnList+'
FROM
(
SELECT RecordID, TimeLog, DateLog FROM TESTPIS.dbo.tblDateTimeLog WHERE isDeleted=0
) AS T
PIVOT
(
MIN(TimeLog) FOR DateLog IN ('+@ColumnList+')
) as P'
EXEC (@SQL)
我想要返回的内容就像DATEDIFF(MINUTES,MIN(TimeLog),MAX(TimeLog)
我尝试用此替换查询中的MIN(TimeLog)
SUM(DATEDIFF(MINUTES,MIN(TimeLog),MAX(TimeLog))
但是,我收到了这个错误
Incorrect syntax near '('.
答案 0 :(得分:2)
select P.RecordID,
P.[2013-06-01],
P.[2013-06-02],
P.[2013-06-03],
P.[2013-06-04],
P.[2013-06-05]
from (
select RecordID,
TimeLog,
DateLog
from YourTable
) as T
pivot(min(TimeLog) for DateLog in ([2013-06-01],
[2013-06-02],
[2013-06-03],
[2013-06-04],
[2013-06-05])) as P
要动态构建查询,您必须首先弄清楚列列表应包含的内容。
select distinct DateLog
from YourTable
order by 1
该查询的结果必须转换为以逗号分隔的列表,因为这样的数字是无效的列名,您可以使用quotename()将值括在[]中。
要构建以逗号分隔的列列表,您可以使用for xml path('')
。
select stuff((select distinct ','+quotename(DateLog)
from YourTable
order by 1
for xml path('')), 1, 1, '')
stuff()
可以删除第一个逗号。
然后你只需要将它们放在一起并执行你构建的查询。
declare @SQL nvarchar(max)
declare @ColumnList nvarchar(max)
select @ColumnList = stuff((select distinct ','+quotename(DateLog)
from YourTable
order by 1
for xml path('')), 1, 1, '')
set @SQL = '
select P.RecordID, '+@ColumnList+'
from (
select RecordID,
TimeLog,
DateLog
from YourTable
) as T
pivot(min(TimeLog) for DateLog in ('+@ColumnList+')) as P'
exec (@SQL)
<强>更新
要获取每天最大和最小时间记录值之间的差异,您可以在派生表中的RecordID
和DateLog
上执行分组,并计算min和max之间的差异,并使用使用dateadd计算新时间值的值。
select P.RecordID,
P.[2013-06-01],
P.[2013-06-02],
P.[2013-06-03],
P.[2013-06-04],
P.[2013-06-05]
from (
select RecordID,
dateadd(second, datediff(second, min(TimeLog), max(TimeLog)), convert(time(0), '00:00')) as TimeDiff,
DateLog
from YourTable
group by RecordID,
DateLog
) as T
pivot(min(TimeDiff) for DateLog in ([2013-06-01],
[2013-06-02],
[2013-06-03],
[2013-06-04],
[2013-06-05])) as P
动态版本:
declare @SQL nvarchar(max)
declare @ColumnList nvarchar(max)
select @ColumnList = stuff((select distinct ','+quotename(DateLog)
from YourTable
order by 1
for xml path('')), 1, 1, '')
set @SQL = '
select P.RecordID, '+@ColumnList+'
from (
select RecordID,
dateadd(second, datediff(second, min(TimeLog), max(TimeLog)), convert(time(0), ''00:00'')) as TimeDiff,
DateLog
from YourTable
group by RecordID,
DateLog
) as T
pivot(min(TimeDiff) for DateLog in ('+@ColumnList+')) as P'
exec (@SQL)
答案 1 :(得分:2)
试试这个 -
<强>查询:
IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
RecordID INT
, DateLog DATETIME
, TimeLog TIME
)
INSERT INTO #temp (RecordID, DateLog, TimeLog)
VALUES
(11, '2013-06-01', '08:00:00'), (11, '2013-06-02', '09:00:00'),
(11, '2013-06-03', '10:00:00'), (11, '2013-06-04', '11:00:00'),
(11, '2013-06-05', '12:00:00'), (14, '2013-06-01', '13:00:00'),
(14, '2013-06-02', '14:00:00'), (14, '2013-06-03', '15:00:00'),
(14, '2013-06-04', '16:00:00')
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = 'SELECT *
FROM (
SELECT DateLog, RecordID, tt = CAST(TimeLog AS VARCHAR(8))
FROM #temp
) src
PIVOT (
MAX(tt)
FOR DateLog IN (' + STUFF((
SELECT ', [' + CONVERT(VARCHAR(10), DateLog, 120) + ']'
FROM #temp
GROUP BY DateLog
ORDER BY DateLog
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')
) p'
PRINT @SQL
EXEC sys.sp_executesql @SQL
<强>输出:
SELECT *
FROM (
SELECT DateLog, RecordID, tt = CAST(TimeLog AS VARCHAR(8))
FROM #temp
) src
PIVOT (
MAX(tt)
FOR DateLog IN ([2013-06-01], [2013-06-02], [2013-06-03], [2013-06-04], [2013-06-05])
) p
<强>结果:
RecordID 2013-06-01 2013-06-02 2013-06-03 2013-06-04 2013-06-05
----------- ---------- ---------- ---------- ---------- ----------
11 08:00:00 09:00:00 10:00:00 11:00:00 12:00:00
14 13:00:00 14:00:00 15:00:00 16:00:00 NULL
更新结果: