Sql 分析查询
我正在寻找一个可以转换表中以下信息的查询Sql 分析查询,sql,informix,Sql,Informix,我正在寻找一个可以转换表中以下信息的查询 name:time :state a :10:00 AM:login b :10:05 AM:login a :10:06 AM:chatting a :10:08 AM:Idle b :10:11 AM:chatting a :10:10 AM:Logout b :10:12 AM:Logout 类似这样的情况(假设时间范围为上午10点到上午10:15,作为查询时段) 这只能使用SQL来完成吗?我使用的是Inform
name:time :state
a :10:00 AM:login
b :10:05 AM:login
a :10:06 AM:chatting
a :10:08 AM:Idle
b :10:11 AM:chatting
a :10:10 AM:Logout
b :10:12 AM:Logout
类似这样的情况(假设时间范围为上午10点到上午10:15,作为查询时段)
这只能使用SQL来完成吗?我使用的是Informix 11.5版,我很确定这只需要SQL就可以完成,这将花费我相当多的时间为您提出一个查询,完成后我将在中编辑它。我认为最基本的步骤是首先计算每个条目所用的时间量(通过将每个条目与下一个条目合并并减去以找出时间差来完成),然后一个简单的带总和的分组子句将很容易地将其转换为您描述的形式 编辑:这是我想到的
SELECT l.userid, l.state, SUM(t.minutes) AS duration
FROM Log l
INNER JOIN (
SELECT l1.id, (l2.time - l1.time) AS minutes
FROM Log l1, Log l2
WHERE l2.time == (
-- find the next entry --
SELECT TOP 1 ls.time
FROM Log ls
WHERE ls.Time > l1.Time && ls.userid = l1.userid
ORDER BY ls.Time
)
) t ON l.id == t.id
GROUP BY l.userid, l.state
ORDER BY l.userid
这是半伪代码,我编造了所有的表名和东西,你不能从一次减去另一次,你可能会使用DATEDIFF函数。除此之外,我认为这是它的要点。我认为SQL是最了不起的语言之一,你几乎可以用很少的代码做任何事情 它可以在单个SQL语句中完成。这是证据 安装程序 正确查询
注意这些条件。结果表必须排除“登录”和第一个其他事件之间的时间段;此外,它必须排除“注销”和下一个事件(可能是“登录”)之间的时间段。名称列上的表之间的自连接和时间列上的非对称连接(使用“
”)您可能需要额外的查询级别,以确保两者之间没有其他相同用途的日志行。您也不能在子查询中使用ORDER BY(至少不在ID中)。你可以从一次减去另一次;结果是一个需要的间隔。嗯,我不太明白你所说的“两次之间没有其他相同用途的日志行”是什么意思.您能详细说明一下吗?子查询中没有ORDER BY使这非常困难!我不知道是否有其他方法,但我会考虑的。
SELECT l.userid, l.state, SUM(t.minutes) AS duration
FROM Log l
INNER JOIN (
SELECT l1.id, (l2.time - l1.time) AS minutes
FROM Log l1, Log l2
WHERE l2.time == (
-- find the next entry --
SELECT TOP 1 ls.time
FROM Log ls
WHERE ls.Time > l1.Time && ls.userid = l1.userid
ORDER BY ls.Time
)
) t ON l.id == t.id
GROUP BY l.userid, l.state
ORDER BY l.userid
CREATE TEMP TABLE eventtable
(
name CHAR(3) NOT NULL,
time DATETIME HOUR TO MINUTE NOT NULL,
state CHAR(8) NOT NULL
);
INSERT INTO eventtable(name, time, state) VALUES('a', '10:00', 'login');
INSERT INTO eventtable(name, time, state) VALUES('b', '10:05', 'login');
INSERT INTO eventtable(name, time, state) VALUES('a', '10:06', 'chatting');
INSERT INTO eventtable(name, time, state) VALUES('a', '10:08', 'Idle');
INSERT INTO eventtable(name, time, state) VALUES('b', '10:11', 'chatting');
INSERT INTO eventtable(name, time, state) VALUES('a', '10:10', 'Logout');
INSERT INTO eventtable(name, time, state) VALUES('b', '10:12', 'Logout');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:01', 'login');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:02', 'chatting');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:03', 'Idle');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:04', 'Logout');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:05', 'Idle');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:06', 'Logout');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:07', 'Idle');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:08', 'Logout');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:09', 'login');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:11', 'chatting');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:12', 'Idle');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:13', 'chatting');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:14', 'Idle');
INSERT INTO eventtable(name, time, state) VALUES('c', '10:15', 'Logout');
SELECT r1.name, r1.state, r2.TIME - r1.TIME AS duration
FROM eventtable r1, eventtable r2
WHERE r1.name = r2.name
AND r1.time < r2.time
AND r1.state != 'login'
AND r1.state != 'Logout'
AND r1.time BETWEEN DATETIME(10:00) HOUR TO MINUTE
AND DATETIME(10:15) HOUR TO MINUTE
AND r2.time BETWEEN DATETIME(10:00) HOUR TO MINUTE
AND DATETIME(10:15) HOUR TO MINUTE
AND NOT EXISTS (SELECT 1 FROM eventtable r3
WHERE r3.time > r1.time AND r3.time < r2.time
AND r3.name = r1.name
AND r3.name = r2.name);
name state duration
a chatting 0:02
a Idle 0:02
b chatting 0:01
c chatting 0:01
c Idle 0:01
c Idle 0:01
c Idle 0:01
c chatting 0:01
c Idle 0:01
c chatting 0:01
c Idle 0:01
(r2.time - r1.time)::INTERVAL MINUTE(4) TO MINUTE
CAST (r2.time - r1.time AS INTERVAL MINUTE(4) TO MINUTE)
SELECT r1.name, r1.state, r2.TIME - r1.TIME AS lapse,
r1.time AS start, r2.time AS end
FROM eventtable r1, eventtable r2
WHERE r1.name = r2.name
AND r1.time < r2.time
AND r1.state != 'login'
AND r1.state != 'Logout'
AND r1.time BETWEEN DATETIME(10:00) HOUR TO MINUTE
AND DATETIME(10:15) HOUR TO MINUTE
AND r2.time BETWEEN DATETIME(10:00) HOUR TO MINUTE
AND DATETIME(10:15) HOUR TO MINUTE;
name state lapse start end
a chatting 0:04 10:06 10:10
a chatting 0:02 10:06 10:08
a Idle 0:02 10:08 10:10
b chatting 0:01 10:11 10:12
c chatting 0:13 10:02 10:15
c chatting 0:12 10:02 10:14
c chatting 0:11 10:02 10:13
c chatting 0:10 10:02 10:12
c chatting 0:09 10:02 10:11
c chatting 0:07 10:02 10:09
c chatting 0:06 10:02 10:08
c chatting 0:05 10:02 10:07
c chatting 0:04 10:02 10:06
c chatting 0:03 10:02 10:05
c chatting 0:02 10:02 10:04
c chatting 0:01 10:02 10:03
c Idle 0:12 10:03 10:15
c Idle 0:11 10:03 10:14
c Idle 0:10 10:03 10:13
c Idle 0:09 10:03 10:12
c Idle 0:08 10:03 10:11
c Idle 0:06 10:03 10:09
c Idle 0:05 10:03 10:08
c Idle 0:04 10:03 10:07
c Idle 0:03 10:03 10:06
c Idle 0:02 10:03 10:05
c Idle 0:01 10:03 10:04
c Idle 0:10 10:05 10:15
c Idle 0:09 10:05 10:14
c Idle 0:08 10:05 10:13
c Idle 0:07 10:05 10:12
c Idle 0:06 10:05 10:11
c Idle 0:04 10:05 10:09
c Idle 0:03 10:05 10:08
c Idle 0:02 10:05 10:07
c Idle 0:01 10:05 10:06
c Idle 0:08 10:07 10:15
c Idle 0:07 10:07 10:14
c Idle 0:06 10:07 10:13
c Idle 0:05 10:07 10:12
c Idle 0:04 10:07 10:11
c Idle 0:02 10:07 10:09
c Idle 0:01 10:07 10:08
c chatting 0:04 10:11 10:15
c chatting 0:03 10:11 10:14
c chatting 0:02 10:11 10:13
c chatting 0:01 10:11 10:12
c Idle 0:03 10:12 10:15
c Idle 0:02 10:12 10:14
c Idle 0:01 10:12 10:13
c chatting 0:02 10:13 10:15
c chatting 0:01 10:13 10:14
c Idle 0:01 10:14 10:15