Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在MSSQL上执行此查询_Sql_Sql Server - Fatal编程技术网

如何在MSSQL上执行此查询

如何在MSSQL上执行此查询,sql,sql-server,Sql,Sql Server,我需要进行查询以显示每天的入口(其中TerminalID=1)和出口(其中TerminalID=2),但如果UserID只有这一天的出口标记,则在入口值上使用08:00:00,如果没有出口标记,则在同一天将出口值设置为20:00:00,我需要知道IDUser在这里的天数和每天的时间,那是我的桌子: 我需要的结果是: UserID MarkEntrance MarkExit TimeHere 1 2014-04-01 08:59 2014-04-01 09:5

我需要进行查询以显示每天的入口(其中TerminalID=1)和出口(其中TerminalID=2),但如果UserID只有这一天的出口标记,则在入口值上使用08:00:00,如果没有出口标记,则在同一天将出口值设置为20:00:00,我需要知道IDUser在这里的天数和每天的时间,那是我的桌子:

我需要的结果是:

UserID  MarkEntrance    MarkExit          TimeHere
1     2014-04-01 08:59  2014-04-01 09:59  01:00:00
1     2014-04-01 10:59  2014-04-01 18:59  08:00:00
1     2014-05-01 08:59  2014-05-01 20:00  11:01:00
SELECT TOP 1000
      pna.UserID
      ,Convert(char(10),pna.TransactionTime, 103) as DateOfMark
      ,MarkEntrance = 
CASE WHEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE  convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
      ,MarkExit = 
CASE WHEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END
      ,TimeHere = 
Convert(char(8),
CASE WHEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END - 
CASE WHEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE  convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
, 14)
  FROM NGAC_AUTHLOG as pna
  GROUP BY pna.UserID, Convert(char(10),pna.TransactionTime, 103)
SELECT *, Convert(char(8), MarkExit - MarkEntrance, 14) TimeHere
FROM
(
SELECT
    A.UserID, A.TransactionTime MarkEntrance, ISNULL(ExitTime, DateAdd(hh, 20, CONVERT(VARCHAR(10), A.TransactionTime, 101))) MarkExit 
FROM NGAC_AUTHLOG A
OUTER APPLY
(
SELECT MIN(TransactionTime) ExitTime
  FROM NGAC_AUTHLOG B
  WHERE B.TerminalID = 2
  AND B.UserID = A.UserID
  AND B.TransactionTime > A.TransactionTime
) B
WHERE A.TerminalID = 1

UNION ALL

--This looks for orphan Exit Record
SELECT A.UserID, DateAdd(hh, 8, CONVERT(VARCHAR(10), max(A.TransactionTime), 101)), max(A.TransactionTime)
FROM NGAC_AUTHLOG A
WHERE A.TerminalID = 2 
AND EXISTS
    (SELECT 1 
    FROM
       (SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T2Date, COUNT(*) T2Count
       FROM NGAC_AUTHLOG
       WHERE TerminalID = 2
       GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) X
       LEFT JOIN
       (SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T1Date, COUNT(*) T1Count
       FROM NGAC_AUTHLOG
       WHERE TerminalID = 1
       GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) Y
          ON X.UserID = Y.UserID
          AND X.T2Date = Y.T1Date
    WHERE X.T2Count > ISNULL(Y.T1Count,0)
    AND X.UserID = A.UserID
    AND X.T2Date = CONVERT(VARCHAR(10), TransactionTime, 101)
    )
GROUP BY A.UserID, CONVERT(VARCHAR(10), TransactionTime, 101)
) X
我能做到这一点:

UserID  MarkEntrance    MarkExit          TimeHere
1     2014-04-01 08:59  2014-04-01 09:59  01:00:00
1     2014-04-01 10:59  2014-04-01 18:59  08:00:00
1     2014-05-01 08:59  2014-05-01 20:00  11:01:00
SELECT TOP 1000
      pna.UserID
      ,Convert(char(10),pna.TransactionTime, 103) as DateOfMark
      ,MarkEntrance = 
CASE WHEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE  convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
      ,MarkExit = 
CASE WHEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END
      ,TimeHere = 
Convert(char(8),
CASE WHEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END - 
CASE WHEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE  convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
, 14)
  FROM NGAC_AUTHLOG as pna
  GROUP BY pna.UserID, Convert(char(10),pna.TransactionTime, 103)
SELECT *, Convert(char(8), MarkExit - MarkEntrance, 14) TimeHere
FROM
(
SELECT
    A.UserID, A.TransactionTime MarkEntrance, ISNULL(ExitTime, DateAdd(hh, 20, CONVERT(VARCHAR(10), A.TransactionTime, 101))) MarkExit 
FROM NGAC_AUTHLOG A
OUTER APPLY
(
SELECT MIN(TransactionTime) ExitTime
  FROM NGAC_AUTHLOG B
  WHERE B.TerminalID = 2
  AND B.UserID = A.UserID
  AND B.TransactionTime > A.TransactionTime
) B
WHERE A.TerminalID = 1

UNION ALL

--This looks for orphan Exit Record
SELECT A.UserID, DateAdd(hh, 8, CONVERT(VARCHAR(10), max(A.TransactionTime), 101)), max(A.TransactionTime)
FROM NGAC_AUTHLOG A
WHERE A.TerminalID = 2 
AND EXISTS
    (SELECT 1 
    FROM
       (SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T2Date, COUNT(*) T2Count
       FROM NGAC_AUTHLOG
       WHERE TerminalID = 2
       GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) X
       LEFT JOIN
       (SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T1Date, COUNT(*) T1Count
       FROM NGAC_AUTHLOG
       WHERE TerminalID = 1
       GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) Y
          ON X.UserID = Y.UserID
          AND X.T2Date = Y.T1Date
    WHERE X.T2Count > ISNULL(Y.T1Count,0)
    AND X.UserID = A.UserID
    AND X.T2Date = CONVERT(VARCHAR(10), TransactionTime, 101)
    )
GROUP BY A.UserID, CONVERT(VARCHAR(10), TransactionTime, 101)
) X
但在我的查询中,我只知道UserID的第一个入口和最后一个出口,但他每天可以有很多分数


(我使用了最小值和最大值,但这种方式只显示一个大标记,合并当天的所有标记)试试这样的方法。注意,我还没有运行查询,所以可能有一个简单的语法错误(主要是在转换中-真的不确定),如果有问题,请在评论中告诉我

;WITH minEntranceInDay as(
    SELECT MIN(transactionTime) EntranceTime,Convert(DateTime( Convert(char(10),na.TransactionTime)), 103) Day, UserId    
    FROM NGAC_AUTHLOG WHERE TerminalId = 1
    GROUP BY Convert(DateTime( Convert(char(10),na.TransactionTime)), 103), UserId
), maxExitInDay as(
    SELECT MAX(transactionTime) ExitTime, Convert(DateTime( Convert(char(10),na.TransactionTime)) Day, UserId    
    FROM NGAC_AUTHLOG WHERE TerminalId = 2
    GROUP BY Convert(DateTime( Convert(char(10),na.TransactionTime)), 103), UserId
), usersAndDates as(
    SELECT DISTINCT Convert(DateTime( Convert(char(10),na.TransactionTime))  Day, UserId    
    FROM NGAC_AUTHLOG 
), GroupedData As (
    SELECT ud.UserId, COALESCE(me.minEntranceInDay,Dateadd(h,8,ud.Day)) EntranceTime, COALESCE(mx.maxExitInDay,Dateadd(h,20,ud.Day)) ExitDate
    FROM usersAndDates ud 
    LEFT JOIN minEntranceInDay me ON me.UserId = ud.UserId AND me.Day = ud.Day 
    LEFT JOIN maxExitInDay mx ON mx.UserId = ud.UserId AND mx.Day = ud.Day
)
SELECT *, DATEDIFF(h,EntranceTime,ExitTime)+":"+DATEDIFF(m,EntranceTime,ExitTime)+":"+DATEDIFF(s,EntranceTime,ExitTime) TimeHere
FROM GroupedData

试试这样的。第一个联合部分匹配入口到出口和孤儿入口的所有记录。工会的第二部分负责处理孤儿出境记录

解决方案1:

UserID  MarkEntrance    MarkExit          TimeHere
1     2014-04-01 08:59  2014-04-01 09:59  01:00:00
1     2014-04-01 10:59  2014-04-01 18:59  08:00:00
1     2014-05-01 08:59  2014-05-01 20:00  11:01:00
SELECT TOP 1000
      pna.UserID
      ,Convert(char(10),pna.TransactionTime, 103) as DateOfMark
      ,MarkEntrance = 
CASE WHEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE  convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
      ,MarkExit = 
CASE WHEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END
      ,TimeHere = 
Convert(char(8),
CASE WHEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MAX(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 2 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 20:00:00')
END - 
CASE WHEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID ) IS NOT NULL
THEN 
(SELECT MIN(TransactionTime) FROM [NGAC_AUTHLOG] as na WHERE na.TerminalID = 1 AND Convert(char(10),na.TransactionTime, 103) = Convert(char(10),pna.TransactionTime, 103) AND na.UserID = pna.UserID )
ELSE  convert(datetime,Convert(char(10),pna.TransactionTime, 103) + ' 08:00:00')
END
, 14)
  FROM NGAC_AUTHLOG as pna
  GROUP BY pna.UserID, Convert(char(10),pna.TransactionTime, 103)
SELECT *, Convert(char(8), MarkExit - MarkEntrance, 14) TimeHere
FROM
(
SELECT
    A.UserID, A.TransactionTime MarkEntrance, ISNULL(ExitTime, DateAdd(hh, 20, CONVERT(VARCHAR(10), A.TransactionTime, 101))) MarkExit 
FROM NGAC_AUTHLOG A
OUTER APPLY
(
SELECT MIN(TransactionTime) ExitTime
  FROM NGAC_AUTHLOG B
  WHERE B.TerminalID = 2
  AND B.UserID = A.UserID
  AND B.TransactionTime > A.TransactionTime
) B
WHERE A.TerminalID = 1

UNION ALL

--This looks for orphan Exit Record
SELECT A.UserID, DateAdd(hh, 8, CONVERT(VARCHAR(10), max(A.TransactionTime), 101)), max(A.TransactionTime)
FROM NGAC_AUTHLOG A
WHERE A.TerminalID = 2 
AND EXISTS
    (SELECT 1 
    FROM
       (SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T2Date, COUNT(*) T2Count
       FROM NGAC_AUTHLOG
       WHERE TerminalID = 2
       GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) X
       LEFT JOIN
       (SELECT UserID, CONVERT(VARCHAR(10), TransactionTime, 101) T1Date, COUNT(*) T1Count
       FROM NGAC_AUTHLOG
       WHERE TerminalID = 1
       GROUP BY UserID, CONVERT(VARCHAR(10), TransactionTime, 101)) Y
          ON X.UserID = Y.UserID
          AND X.T2Date = Y.T1Date
    WHERE X.T2Count > ISNULL(Y.T1Count,0)
    AND X.UserID = A.UserID
    AND X.T2Date = CONVERT(VARCHAR(10), TransactionTime, 101)
    )
GROUP BY A.UserID, CONVERT(VARCHAR(10), TransactionTime, 101)
) X
解决方案2: 假设存在孤立退出记录,则该用户当天只有1条退出记录

SELECT *, Convert(char(8), MarkExit - MarkEntrance, 14) TimeHere
FROM
(
SELECT
    A.UserID, A.TransactionTime MarkEntrance, ISNULL(ExitTime, DateAdd(hh, 20, CONVERT(VARCHAR(10), A.TransactionTime, 101))) MarkExit 
FROM NGAC_AUTHLOG A
OUTER APPLY
(
SELECT MIN(TransactionTime) ExitTime
  FROM NGAC_AUTHLOG B
  WHERE B.TerminalID = 2
  AND B.UserID = A.UserID
  AND B.TransactionTime > A.TransactionTime
) B
WHERE A.TerminalID = 1

UNION ALL
--This looks for orphan Exit Record
SELECT A.UserID, DateAdd(hh, 8, CONVERT(VARCHAR(10), A.TransactionTime, 101)), A.TransactionTime
FROM NGAC_AUTHLOG A
WHERE A.TerminalID = 2 
AND NOT EXISTS
    (SELECT 1 
    FROM NGAC_AUTHLOG B
    WHERE B.TerminalID = 1
     AND A.UserID = B.UserID
      AND CONVERT(VARCHAR(10), A.TransactionTime, 101) = CONVERT(VARCHAR(10), B.TransactionTime, 101))  
) X

您能否向查询中添加一个具有预期结果的表?我有点迷失在你想要实现的目标中。但另一方面,这个问题很有趣;)是的,当然!我编辑了我需要的结果:)这似乎是递归CTE的主要候选。Tomas,我们有一个问题,哈哈,用户ID每天可以有超过1个标记,我需要知道每个标记中的时间。(我使用了最小值和最大值,但这样只显示了一个大标记,合并了当天的所有标记)@AlessandroGomes你能在第一篇文章的示例中显示一下吗,因为它会在1/4上查找用户1?我插入了实际结果,并更新了表中的值以描述我所评论的情况。@AlessandroGomes您知道条目1和条目5是相同的吗?如果这是正确的,它将使它变得更加困难?以下是我目前所拥有的:@AlessandroGomes对不起,我放弃了。。。那对我来说太难了!这就是我到目前为止所做的:我正在检查你的查询,但我认为你做对了!!我将很快标记您的答案。我有一个问题:(如果用户在标记退出之前有两个标记类型1(入口),我只需要使用第一个标记来检查
时间here
(在这种情况下,只需忽略第二个入口标记),此查询返回两个入口的
TimeHere
,SQLFiddle:,但这是我需要的最后一次更新。感谢您的帮助!上面的问题有很多变体需要解决。两个入口和两个出口,但第二个入口在第一个出口之前。1个入口和2个出口如何。这看起来可能是向前看,但如果我们结合更大的数据集,复杂性将进一步增加。如果我们有两个出口,在同一天使用最后一个出口,但在你的第一个sqlfiddle(两个入口和两个出口)中,我需要使用第一个入口和最后一个出口。我给你解释正确了吗?这个问题让我头晕目眩哈哈