我需要一个SQL查询来检查一个人在一年中连续两周是否处于活动状态。
例如,
Table1:
Name | Activity | Date
Name1|Basketball| 08-08-2014
Name2|Volleyball| 08-09-2014
Name3|None | 08-10-2014
Name1|Tennis | 08-14-2014
我想检索Name1,因为该人已连续两周活跃。
这是我目前的查询:
SELECT DISTINCT Name
FROM Table1
Where YEAR(Date) = 2014 AND
Activity NOT 'None' AND
这是我需要连续两周检查活动的逻辑的地方。一周可以描述为7到14天后。我正在使用MYSQL。
答案 0 :(得分:2)
我避免故意在where子句中使用YEAR(Date
),并建议你也这样做。使用多行数据上的函数来满足单一标准(2014)对我来说永远不会有意义,而且它会破坏索引的有效性(参见" sargable"在维基百科)。通过日期范围IMHO更容易定义过滤器。
我使用相关子查询来推导nxt_date
,这可能无法很好地扩展,但总体而言,性能最可能取决于您的索引。
select distinct
name
from (
select
t.name
, t.Activity
, t.`Date`
, (
select min(table1.`Date`) from table1
where t.name = table1.name
and table1.Activity <> 'None'
and table1.`Date` > t.`Date`
) as nxt_date
from table1 as t
where ( t.`Date` >= '2014-01-01' and t.`Date` < '2015-01-01' )
and t.Activity <> 'None'
) as sq
where datediff(sq.nxt_date, sq.`Date`) <= 14
;
答案 1 :(得分:1)
您可以使用exists
子查询来执行逻辑:
select t.*
from table1 t
where exists (select 1
from table1 t2
where t2.name = t.name and
t2.date between t.date + 7 and t.date + 14
);
答案 2 :(得分:1)
我不知道它是否与性能相关,但我喜欢简洁的查询:
SELECT t1.Name
FROM Table1 t1, Table1 t2
Where t1.Name=t2.Name AND
t1.Date >= '2014-01-01' AND t1.Date < '2015-01-01' AND
t1.Activity <> 'None' AND
t1.Date < t2.Date AND
datediff(t2.Date, t1.Date) <= 14
我喜欢@ user2067753关于YEAR(date)
。
我使用the answer above的sqlfiddle来检查使用explain
syntax的效果。似乎避免使用VACN's answer或我的查询是有益的(请参阅join vs sub query)
答案 3 :(得分:0)
从我的头脑中,我建议这个查询:
SELECT DISTINCT t1.Name
FROM Table1 AS t1, Table1 AS t2
WHERE t1.Name = t2.Name
AND t2.Date BETWEEN t1.Date-7 AND t1.Date+7;
这个想法基本上是:你打电话给你的桌子两次,选择名字匹配的行,然后只保留第二个日期距离第一个日期最多7天的那些。