2017-08-03 29 views
1

如何計算連續兩次缺席的用戶?我必須創建一張圖表來顯示員工缺勤頻率。PHP MYSQLI計數連續兩個日期的用戶

我的表名= 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,只有人與AL2已經連續兩個日期,其中描述=缺席。

我正在使用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

能否請您發佈的SQL格式的一些示例數據? – sumit

回答

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 ...
  • 您應該嘗試將WHERE中的AND查詢移動到ON子句中。然後你可以使用INNER加入。你會得到同樣的結果,但瞭解這兩者後會對你有所幫助。
+0

不錯。不完整。 – Strawberry

+0

(這是一個內部連接 ​​- 正如EXPLAIN EXTENDED,接下來是SHOW WARNINGS會演示的) – Strawberry

+0

@Strawberry想法通過提示「LEFT JOIN」我會給他更多的選項以便隨後查詢。 – cwallenpoole

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:[email protected]+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;