在SQL中配对项目并减去结果

时间:2011-03-17 09:35:31

标签: mysql select join foreach

我遇到了一个挑战,我无法通过任何正常手段找到答案。我想在一个查询中尽可能多地做,因为我唯一的另一种选择是编写这个函数的脚本,并用无数的子查询循环它。

好的,我在MySQL服务器上有一个日志表,它有以下几列:     密钥,用户ID,日期时间和职位 位置可以是“开始”,“登录”和“结束”。

我想找出每个登录事件的“开始”,“登录”和“结束”之间的区别。 任何人都知道我可以使用的SQL查询?我认为它与查询中的查询有关,但我只能找到JOIN?

我假设我首先选择“开始”事件,然后对于每个“开始”事件,它应该查找“UserID”的下一个第一次登录事件(在“开始”之后但小于下一个“开始”的时间为相同的“UserID”)然后DATE_SUB()找出差异。过滤掉未来“开始”事件后发生的“登录”或“结束”事件非常重要,以防万一没有发生。

如果有人能在Excel中保存我这样做,我将非常感激,因为那时我可以避免因为成千上万的vlookup而感到太脏。我正在考虑在PHP或Perl中执行此操作,并且只使用LIMIT 1 SQL语句创建一个循环,但与单个体面的SQL SELECT语句相比,这可能会创建数千个SQL查询。

2 个答案:

答案 0 :(得分:1)

我不确定MySQL。在MS Sql Server中,我尝试以下内容:

SELECT Key, UserID, DateTime, Position, 
    (DateTime - (SELECT MAX(DateTime) FROM <table> t1 
                 WHERE t1.UserID=UserID AND t1.DateTime < DateTime)) AS DiffToLastEvent
FROM <table>

我实际上没有尝试过这个,但这就是我的开始。这应该从表<table>中选择所有列,并附加一个字段,其中包含当前项目与当前项目之前为用户创建的最年轻项目的时差。

答案 1 :(得分:0)

如果您只有开始和结束日期,这里是基本方法。我不太明白&#34;登录&#34;位置适合,所以你需要更清楚地解释你想要的输出,或者让你的查询满意。此外,查询是在SQL服务器中,因为我没有安装MySQL - 抱歉!

CREATE TABLE LogTable
(
    id int IDENTITY,
    userId nvarchar(20),
    logDate datetime,
    position nvarchar(5)    
)
GO

INSERT INTO LogTable (userId, logDate, position) VALUES ('User1', '2001-01-01', 'start')
INSERT INTO LogTable (userId, logDate, position) VALUES ('User1', '2001-01-02', 'end')
INSERT INTO LogTable (userId, logDate, position) VALUES ('User1', '2001-01-05', 'start')
INSERT INTO LogTable (userId, logDate, position) VALUES ('User1', '2001-01-08', 'end')
INSERT INTO LogTable (userId, logDate, position) VALUES ('User2', '2001-01-01', 'start')
INSERT INTO LogTable (userId, logDate, position) VALUES ('User2', '2001-01-03', 'end')
INSERT INTO LogTable (userId, logDate, position) VALUES ('User2', '2001-01-06', 'start')
INSERT INTO LogTable (userId, logDate, position) VALUES ('User2', '2001-01-07', 'end')
GO

SELECT  log1.userId, log1.logDate AS [start], log2.logDate AS [end], 
        DATEDIFF(d, log1.logDate, log2.logDate) AS [Diff. in Days]
FROM    LogTable log1 JOIN
        LogTable log2 ON log1.userId = log2.userId
WHERE   log1.position = 'start'
AND     log2.position = 'end'
AND     log2.logDate > log1.logDate
AND     NOT EXISTS (
    SELECT  * 
    FROM    LogTable logDateCheck
    WHERE   logDateCheck.userId = log1.userId
    AND     logDateCheck.logDate >= log1.logDate
    AND     logDateCheck.logDate <= log2.logDate
    AND     logDateCheck.id NOT IN (log1.id, log2.id))
GO

输出是:

Output from query