如何才能连续两次缺勤统计用户?我必须创建一个图表来显示员工的频繁缺勤情况。
我的表名= incidencias
id | name | dateA | description
1 | al |2017-08-01| absence
2 | al |2017-08-02| absence
3 | alex |2017-08-01| absence
4 | alex |2017-08-02| absence
5 | alex |2017-08-03| absence
6 | al2 |2017-08-01| absence
7 | al2 |2017-08-02| absence
我希望结果为2,只有al和al2有两个连续的日期,其中description =缺席。
我使用php来运行查询,我确实尝试了这个代码我发现但是我在sqlfiddle中测试它并且效果很好。但不是在我的主机上。我认为这是针对PostgreSQL的。
$query2 = mysqli_query($conn, "SELECT name,
sum(diff) as days,
(dateA) as work_start,
(dateA) as work_end
FROM (SELECT name,
dateA,
diff
FROM (select name,
dateA,
nvl(dateA- lag(dateA) over (partition by name order by dateA),1) as diff
from incidencias
where description = 'absence'
) t1
where diff = 1
) t2
group by name
having sum(diff) = 2");
$row_cnt = mysqli_num_rows($query2);
printf("Result set has %d rows.\n", $row_cnt);
我真的很感激。
答案 0 :(得分:1)
所以,这通常是通过JOIN
到同一张桌子来完成的。
SELECT oinc.*
FROM incidencias oinc
LEFT JOIN
incidencias iinc
ON (oinc.name = iinc.name AND oinc.description = iinc.description)
WHERE description = 'absence'
AND oinc.dateA = DATE_ADD( iinc.dateA, 'INTERVAL 1 DAY');
所以,逐行:
SELECT oinc.* -- grab me everything from the oinc table
FROM incidencias oinc -- We're going to call incidencias "oinc" in this query
-- "oinc" is now an alias for "incidencias"
LEFT JOIN -- I want a result whether or not the result is duplicated.
-- (Technically, by including the condition that it not be duplicated
-- this is the same thing as an "INNER JOIN".)
incidencias iinc -- We're looking at the same table, better call it something else
ON (oinc.name = iinc.name AND oinc.description = iinc.description)
-- We're matching the name and the description between the two
-- aliases of the table (oinc, iicn)
WHERE description = 'absence' -- Should be obvious
AND oinc.dateA = DATE_ADD( iinc.dateA, 'INTERVAL 1 DAY'); -- the iinc alias
-- has a date which is one day less than the oinc alias
一些旁注:
left
加入,以便您稍后可以省略AND ...
。AND
查询从WHERE
移到ON
子句中。然后,您可以使用INNER
加入。你会得到相同的结果,但知道这两个结果会在以后帮助你。答案 1 :(得分:0)
这是一种方式(可能有一个更简单的解决方案,但无论如何这应该很快)...
SELECT COUNT(*)
FROM
( SELECT name
, MAX(i) i
FROM
( SELECT x.*
, CASE WHEN @prev_name = name THEN
CASE WHEN @prev_date = datea - INTERVAL 1 DAY THEN @i:=@i+1 ELSE @i:=1 END
ELSE @i:=1 END i
, @prev_name := name
, @prev_date := datea
FROM my_table x
, ( SELECT @prev_name:=null,@prev_date:=null, @i:=1) vars
WHERE x.description = 'absence'
ORDER
BY name
, datea
) b
GROUP
BY name
HAVING i = 2
) p;