2017-08-03 1 views
1

2つの連続した休暇のユーザーしかカウントできません。私は従業員の休暇を表示するためのグラフを作成する必要があります。PHP MYSQLIは2つの連続した日付のユーザーをカウントします

私のテーブル名=私は結果は2になりたい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 

は、Alのみと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 ...後で省略することができるように参加します。
  • ANDクエリをWHEREからON句に移動することを試してください。次に、INNERの結合を使用できます。あなたは同じ結果を得るでしょうが、両方を知ることは後であなたを助けます。
+0

ニース。しかし、不完全です。 – Strawberry

+0

(これは内部結合です - EXPLAIN EXTENDEDに続いてSHOW WARNINGSが示すように) – Strawberry

+0

@Strawberry Thought "LEFT JOIN"を提案することで、後でクエリを再生するオプションを増やすことができます。 – cwallenpoole

0

ここに1つの方法は、(そこに簡単な解決策かもしれないが、これはとにかく高速である必要があります)です...

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; 
関連する問題