2016-08-02 98 views
0

我有一个如下的SQL语句,我希望以分钟为单位检查数据,其中D.DatalogValue没有任何值,它不会显示为空值或零值无论是。下面的输出结果示例将显示为2016-06-01 00:32:29为缺少createdDate。在几分钟内检查SQL中的丢失时间间隔

SELECT 
    A.DefID, A.ObjID, 
    C.ObjName, C.Dev_ID, 
    A.Pro_ID, A.ArrayIndex, 
    A.DefType, A.TObjID, A.DimeId, A.DefId, 
    D.DatalogValue, D.PanelDt, D.CreatedDate 
FROM 
    Table A, Table C, Table D 
WHERE 
    A.ObjID = C.ObjID 
    AND C.ObjID = '2627' 
    AND A.DefID = D.DefID 
    AND D.CreatedDate BETWEEN '2016-06-01' AND '2016-06-02' 
ORDER BY 
    C.ObID,C.ObjName; 

的样本数据:

Create Date    DatalogValue 
------------------------------------- 
2016-06-01 00:29:29  0.01 
2016-06-01 00:30:29  0.02 
2016-06-01 00:31:29  0.03 

2016-06-01 00:33:29  0.04 

通过使用所提供的解决方案,我已经走出了一条SQL语句,但它仍然没有能够表现出我想要的结果。我不知道我在做这部分错我的代码如下:

DECLARE @StartDate DATETIME = '2016-07-01'; 
DECLARE @EndDate DATETIME = '2016-07-31'; 

WITH Check_Dates AS (
SELECT @StartDate [Date] 
UNION ALL 
SELECT DATEADD(MINUTE, 1, [Date]) FROM Check_Dates 
WHERE [Date] < DATEADD(DAY, 1, @EndDate) 
) 

SELECT 
FORMAT(d.Date, 'yyyy-MM-dd HH:mm') [Created Date] 

FROM Check_Dates d 
WHERE 
NOT EXISTS(
SELECT 
Format(D.CreatedDate, 'yyyy-MM-dd HH:mm')as created_dt 

FROM TABLE A 
,TABLE C 
,TABLE D 
WHERE A.ObjID=C.ObjID 
AND C.ObjID IN('3915') 
AND A.DefID=D.DefID 
AND D.CreatedDate BETWEEN '2016-07-01' AND '2016-08-01' 
) 

OPTION (MAXRECURSION 0); 
+1

无论你需要一个'outer join'还是一个'outer'表都带有'outer join' - 难以说没有样本数据和预期的结果(以及可能的表结构)。 – sgeddes

+0

@sgeddes您好我重新编辑我的文章样本数据,因为我面临的问题是它没有插入零或空它会直接跳过它,我需要显示哪些分钟没有出现。 – user1391079

+0

创建一个包含特定时间间隔内的所有分钟的表格。外部加入与完全合格的分钟相反。只采取有参考日期但没有数据的结果。 –

回答

0

一个解决方案是使用一个CTE创建的DATETIME秒的名单,然后LEFT JOIN这些到您的原始查询。您也可以创建一对表格(如注释中所述) - 谷歌DimDate和/或DimTime。

喜欢的东西(未经测试):

DECLARE @StartDate DATETIME = '2016-06-01'; 
DECLARE @EndDate DATETIME = '2016-06-02'; 

WITH Dates AS (
    SELECT @StartDate [Date] 
    UNION ALL 
    SELECT DATEADD(SECOND, 1, [Date]) FROM Dates 
    WHERE [Date] < DATEADD(DAY, 1, @EndDate) 
) 
SELECT 
d.Date [Created Date] 
,COALESCE(Qry.DatalogValue, 0) DatalogValue 
FROM Dates d 
LEFT JOIN (
    Your query goes here 
) Qry 
ON d.Date = Qry.CreatedDate 
OPTION (MAXRECURSION 0) 
+0

你好,谢谢你的建议,我得到了一个语法错误,在第9行。我修好后,会让你知道它的工作与否 – user1391079

+0

只是与你检查我应该为D.DatalogValue放什么?介意分享 – user1391079

+0

抱歉,错字 - 这只是您在子查询中选择的值,我会更新答案。 –

0

你的解决方案似乎非常危险的我。你确定要比较几秒吗?我会截断到几分钟。我建议更强大的解决方案:

WITH Dates AS 
(--Your dates and values 
    SELECT * FROM (VALUES 
    ('2016-06-01 00:29:29', 0.01), 
    ('2016-06-01 00:30:29', 0.02), 
    ('2016-06-01 00:31:29', 0.03), 
    ('2016-06-01 00:33:29', 0.04)--,('2016-06-01 01:00:28', 0.05) 
    ) T(CreateDate, CatalogValues) 
), Minute10 AS --Generate numbers from 0-999999 
(
    SELECT * FROM (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(0)) T1(Value) 
), Minute1000 AS 
(
    SELECT M1.Value FROM Minute10 M1 CROSS JOIN Minute10 M2 CROSS JOIN Minute10 
), Minute1000000 AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1))-1 Value 
    FROM Minute1000 
    CROSS JOIN Minute1000 M2 
), RangeValues AS --for simplicity, min and max values from dates 
(
    SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, MIN(CreateDate)), 0) MinDate, 
      DATEADD(MINUTE, DATEDIFF(MINUTE, 0, MAX(CreateDate)), 0) MaxDate 
    FROM Dates 
) 
SELECT TOP(1+DATEDIFF(MINUTE, (SELECT MinDate FROM RangeValues), (SELECT MaxDate FROM RangeValues))) 
DATEADD(MINUTE,Value,MinDate) ExpectedDate, CreateDate, CatalogValues 
FROM Minute1000000 
CROSS APPLY (SELECT MinDate FROM RangeValues) T 
LEFT JOIN Dates ON DATEADD(MINUTE,Value,MinDate)=DATEADD(MINUTE, DATEDIFF(MINUTE, 0, CreateDate), 0) 

请注意,所有日期都被截断为分钟。您可以通过删除数字生成部分来简单地进行查询(数字可以放置在实用程序表中,如果这是您需要的全部值,则可以放置1440个值)。最小值和最大值可以预先计算。

这导致下面的输出(可以处理的范围的minDate +999999分钟,可以简单地扩展):

ExprectedDate    CreateDate   CatalogValues 
2016-06-01 00:29:00.000 2016-06-01 00:29:29 0.01 
2016-06-01 00:30:00.000 2016-06-01 00:30:29 0.02 
2016-06-01 00:31:00.000 2016-06-01 00:31:29 0.03 
2016-06-01 00:32:00.000 NULL     NULL 
2016-06-01 00:33:00.000 2016-06-01 00:33:29 0.04 

说明:

日期只是源表。表Minute10 .. Minute1000000将生成0到999999之间的数字(10个交叉连接10 = 100,100个交叉连接x3 = 100^3 = 1000000)。上表中的记录被编号以获得顺序值。从评估所有百万价值RangeValues包含MAX和MIN日期,为简单起见

算法:。

由于需要从MIN最新记录到MAX日起每分钟,你评价TOP DATETIFF(MINUTE,MIN,MAX)+1记录(+1避免Fencepost错误)所有需要的表格都会加入(CROSS APLLY将MIN列添加到每条记录中),预计日期按MIN(分钟)日期+以分钟为单位的顺序值计算。 ast加入,从左到右匹配与源表每分钟生成的日期。如果匹配,则记录被追加(加入)。如果不匹配,则附加NULL。注意`DATEADD(MINUTE,DATEDIFF(MINUTE,0,@someDate),0)'从日期截断秒数。

+0

嗨,你好,你的解决方案有点复杂,我想你想更详细地解释一下吗? – user1391079

相关问题