我有一个包含以下字段的表,我需要一个视图/查询,它将为表中的每个帐户列出第一行开头的行 Descr = ON TEST(如果存在)" THRU"描述=关闭测试。
它需要列出中间的所有行,但忽略所有其他行。
提前致谢。
account date descr
1234 10/05/15 17:45:23 MISC
1234 10/05/15 17:45:24 ON TEST
1234 10/05/15 17:51:32 DOOR
1234 10/05/15 17:52:52 CLOSE
1234 10/05/15 17:55:08 OPEN
1234 10/05/15 17:56:56 CLOSE
1234 10/05/15 18:08:16 OPEN
1234 10/05/15 18:10:28 CLOSE
1234 10/05/15 18:10:32 CLOSE
1234 10/05/15 18:15:02 OFF TEST
1234 10/05/15 19:10:32 CLOSE
期望的结果::
1234 10/05/15 17:45:24 ON TEST
1234 10/05/15 17:51:32 DOOR
1234 10/05/15 17:52:52 CLOSE
1234 10/05/15 17:55:08 OPEN
1234 10/05/15 17:56:56 CLOSE
1234 10/05/15 18:08:16 OPEN
1234 10/05/15 18:10:28 CLOSE
1234 10/05/15 18:10:32 CLOSE
1234 10/05/15 18:15:02 OFF TEST
答案 0 :(得分:2)
在一般情况下获取开/关日期有点棘手。这符合你的规则,应该得到日期。
select t.account, ton.on_date,
min(case when t.date >= ton.on_date) as off_date
from t join
(select account, min(date) as on_date
from t
where t.descr = 'ON TEST'
group by account
) ton
on t.account = ton.account
where t.descr = 'OFF TEST'
group by t.account, ton.on_date;
获取原始行:
with onoff as (
select t.account, ton.on_date,
min(case when t.date >= ton.on_date) as off_date
from t join
(select account, min(date) as on_date
from t
where t.descr = 'ON TEST'
group by account
) ton
on t.account = ton.account
where t.descr = 'OFF TEST'
group by t.account, ton.on_date
)
select t.*
from t join
onoff
on t.account = onoff.account
where t.date between onoff.on_date and onoff.off_date;
如果你认为在第一个" on"之前没有" off"则问题会简单得多。例如:
select t.*
from t join
(select account,
min(case when t.descr = 'ON TEST' then date end) as on_date,
min(case when t.descr = 'OFF TEST' then date end) as off_date
from t
group by account
) onoff
on t.account = ton.account
where t.date between onoff.on_date and onoff.off_date;
答案 1 :(得分:1)
双重自我加入,一个用于开始和停止:
select t.account, t.date, t.descr
from tablename t
join tablename tstart on t.account = tstart.account
and tstart.descr = 'ON TEST'
join tablename tstop on t.account = tstop.account
and tstop.descr = 'OFF TEST'
where t.date between tstart.date and tstop.date
或者,加倍EXISTS
:
select t.account, t.date, t.descr
from tablename t
where exists (select 1 from tablename tstart
where t.account = tstart.account
and tstart.descr = 'ON TEST'
and t.date >= tstart.date)
and exists (select 1 from tablename tstop
where t.account = tstop.account
and tstop.descr = 'ON TEST'
and t.date <= tstop.date)
答案 2 :(得分:0)
选择ON TEST date和OFF TEST date之间的所有行。
select *
from table_name
where date >= (select date from table_name where descr = 'ON TEST')
and date <= (select date from table_name where descr = 'OFF TEST')
order by date asc
答案 3 :(得分:0)
您需要比较'ON TEST'和'OFF TEST'的最新时间戳,并检查'ON'是否大于'OFF':
SELECT *
FROM
( SELECT t.*,
(SELECT MAX(date) -- most recent 'ON TEST'
FROM tab AS t2
WHERE t2.account = t.account
AND t2.date <= t.date
AND t2.descr = 'ON TEST') AS last_on,
(SELECT MAX(date) -- most recent 'OFF TEST'
FROM tab AS t2
WHERE t2.account = t.account
AND t2.date < t.date
AND t2.descr = 'OFF TEST') AS last_off
FROM tab AS t
) AS dt
WHERE last_on >= COALESCE(last_off, last_on) -- 'ON' > 'OFF' or no previous 'OFF'
在SQL Server 2012中,使用OVER
会更容易,例如
MAX(CASE WHEN descr = 'ON TEST' THEN date END)
OVER (PARTITION BY account
ORDER BY date
ROWS UNBOUNDED PRECEDING) AS last_on