mko*_*ker 5 sql sql-server join datetime2
我正在编写一个脚本来分析SQL Server 2008数据库中数千个表中包含的一些数据.
为简单起见,表格可以分为4-8个半相关表格.通过半关联,我的意思是它们是同一项的数据集合,但它们没有任何实际的SQL关系.每个表由一个日期-时间戳(的datetime2数据类型),值(可以是一个bit,int或float根据特定的项目),和当前不感兴趣的一些其它列.日期时间标记在几秒钟内每15分钟(在四分之一小时内)设置; 然而,并非所有数据都是同时准确记录的......
例如:
表格1:
TIMESTAMP VALUE
2014-11-27 07:15:00.390 1
2014-11-27 07:30:00.390 0
2014-11-27 07:45:00.373 0
2014-11-27 08:00:00.327 0
Run Code Online (Sandbox Code Playgroud)
TABLE2:
TIMESTAMP VALUE
2014-11-19 08:00:07.880 0
2014-11-19 08:15:06.867 0.0979999974370003
2014-11-19 08:30:08.593 0.0979999974370003
2014-11-19 08:45:07.397 0.0979999974370003
Run Code Online (Sandbox Code Playgroud)
表3
TIMESTAMP VALUE
2014-11-27 07:15:00.390 0
2014-11-27 07:30:00.390 0
2014-11-27 07:45:00.373 1
2014-11-27 08:00:00.327 1
Run Code Online (Sandbox Code Playgroud)
如您所见,并非所有表都以相同的季度开始TIMESTAMP.基本上,我所追求的是一个查询,它将从3个表中最早的每个15分钟间隔返回3个表中每个表的VALUE TIMESTAMP.对于给出的示例,我想在2014-11-27 07:15开始(不关心秒......因此,需要允许时间戳为+ - 1分钟左右).当没有特定TIMESTAMP的记录时,返回NULL值是可以的.因此,我列出的示例的查询将返回如下内容:
TIMESTAMP VALUE1 VALUE2 VALUE3
2014-11-27 07:15 1 NULL 0
2014-11-27 07:30 0 NULL 0
2014-11-27 07:45 0 NULL 1
2014-11-27 08:00 0 NULL 1
...
2014-11-19 08:00 0 0 1
2014-11-19 08:15 0 0.0979999974370003 0
2014-11-19 08:30 0 0.0979999974370003 0
2014-11-19 08:45 0 0.0979999974370003 0
Run Code Online (Sandbox Code Playgroud)
我希望这是有道理的.任何帮助/指针/指导将不胜感激.
我要做的第一件事是将时间戳标准化为分钟。您可以通过更新现有列来完成此操作
UPDATE TABLENAME
SET TIMESTAMP = dateadd(minute,datediff(minute,0,TIMESTAMP),0)
Run Code Online (Sandbox Code Playgroud)
或在新列中
ALTER TABLE TABLENAME ADD COLUMN NORMTIME DATETIME;
UPDATE TABLENAME
SET NORMTIME = dateadd(minute,datediff(minute,0,TIMESTAMP),0)
Run Code Online (Sandbox Code Playgroud)
有关保留日期的详细信息,请参阅此帖子:Floor a date in SQL Server
下一步是创建一个表,其中包含您期望看到的所有时间戳(标准化)——即每 15 个——每行一个。在我的示例中,我们将该表称为 TIME_PERIOD,将列称为 EVENT_TIME(无论您想怎样称呼它)。
有很多方法可以使这样的表递归 CTE、ROW_NUMBER(),甚至暴力破解。我把这部分留给你。
现在的问题是简单的选择,使用左连接和有效值的过滤器,如下所示:
SELECT TP.EVENT_TIME, a.VALUE as VALUE1, b.VALUE as VALUE2, c.VALUE as VALUE3
FROM TIME_PERIOD TP
LEFT JOIN TABLE1 a ON a.[TIMESTAMP] = TP.EVENT_TIME
LEFT JOIN TABLE2 b ON b.[TIMESTAMP] = TP.EVENT_TIME
LEFT JOIN TABLE3 c ON c.[TIMESTAMP] = TP.EVENT_TIME
WHERE COALESCE(a.[TIMESTAMP], b.[TIMESTAMP], c.[TIMESTAMP]) is not null
ORDER BY TP.EVENT_TIME DESC
Run Code Online (Sandbox Code Playgroud)
如果它们是不同的类型,则 where 可能会变得更复杂,因此您始终可以使用它(虽然不如合并好,但始终有效):
WHERE a.[TIMESTAMP] IS NOT NULL OR
b.[TIMESTAMP] IS NOT NULL OR
c.[TIMESTAMP] IS NOT NULL
Run Code Online (Sandbox Code Playgroud)