4

私はemp用のテーブルを持っています。出席シート:

emp_No Absent_Date
-------------------
111     01/03/2012
111     05/05/2012
222     13/02/2012
222     01/03/2012
222     02/03/2012
222     29/04/2012
222     09/09/2012
333     15/05/2012
333     18/09/2012
333     19/09/2012

以下のような行を返す必要があります。

emp_No Absent_Date
-------------------
222     13/02/2012
222     01/03/2012
222     02/03/2012
222     29/04/2012

従業員番号 222 だけが 3 か月連続で欠勤しているためです。

4

3 に答える 3

5

あなたがやろうとしているのは、欠勤を連続する月ごとにグループ化することです。dense_rank()関数と基本的なウィンドウ関数をサポートする合理的なデータベースを使用していると仮定します。

アイデアは、欠勤のある月を順番に見つけることです。次に、各従業員の各シーケンスの月数を数え、3 か月を超えるものを保持します。

クエリは、月を月数 (年と月の 12 倍) に変換することによってこれを行います。次に、単純な観察を使用します。月数から一連の数字を引いたものは、連続する月の定数です。通常、row_number()シーケンスに使用します。あなたは月に重複して欠勤しているので、私は を使用してdense_rank()います。

select emp_no, absent_date
from (select a.*,
             max(monthnum) over (partition by emp_no, groupnum) as lastmonth,
             min(monthnum) over (partition by emp_no, groupnum) as firstmonth
      from (select a.*,
                   monthnum - dense_rank() over (partition by emp_no order by monthnum) as groupnum
            from (select a.*,
                         year(a.absent_date)*12+month(a.absent_date) as monthnum
                  from Attendance a
                 ) a
           ) a
     ) a
where lastmonth - firstmonth >= 2

最後に、従業員数だけではなく、不在の日付が必要なので、ウィンドウ関数を使用して最初と最後の月を見つけ、それらの差をフィルターとして使用します。

于 2013-01-06T15:41:58.230 に答える
2

最も簡単なのは、テーブルの自己結合を3回実行することです。そのたびに、日付に1か月が追加されます。

SELECT DISTINCT S1.emp_No
FROM attendance_sheet S1
JOIN attendance_sheet S2
ON S1.emp_No = S2.emp_No
AND Month(S1.Absent_Date + 1 MONTH) = Month(S2.Absent_Date)
AND Year(S1.Absent_Date + 1 MONTH) = Year(S2.Absent_Date)
JOIN attendance_sheet S3
ON S2.emp_No = S3.emp_No
AND Month(S2.Absent_Date + 1 MONTH) = Month(S3.Absent_Date)
AND Year(S2.Absent_Date + 1 MONTH) = Year(S3.Absent_Date)

これはあなたにすべてのユニークなものを与えるでしょうemp_No。ここで、必要な結果を得るには、別の結合を行う必要があります(それぞれIN、読みやすくするために使用します)。

SELECT * 
FROM attendance_sheet
WHERE emp_No IN (
  SELECT S1.emp_No
  FROM attendance_sheet S1
  JOIN attendance_sheet S2
  ON S1.emp_No = S2.emp_No
  AND Month(S1.Absent_Date + 1 MONTH) = Month(S2.Absent_Date)
  AND Year(S1.Absent_Date + 1 MONTH) = Year(S2.Absent_Date)
  JOIN attendance_sheet S3
  ON S2.emp_No = S3.emp_No
  AND Month(S2.Absent_Date + 1 MONTH) = Month(S3.Absent_Date)
  AND Year(S2.Absent_Date + 1 MONTH) = Year(S3.Absent_Date)
)

試してみるSQLフィドルを参照してください(構文を追加する月を標準SQLからMySQLに変更する必要がありました)。

于 2013-01-06T10:09:37.750 に答える
1

このコードを試してください:

SELECT DISTINCT * FROM
(
SELECT  E1.Attendance _No,
        E1.Absent_Date
FROM Attendance  E1
JOIN Attendance  E2
ON E2.Attendance _No = E1.Attendance _No
AND MONTH(E2.Absent_Date)  = MONTH(E1.Absent_Date) + 1
JOIN Attendance  E3
ON E3.Attendance _No = E2.Attendance _No
AND MONTH(E3.Absent_Date) = MONTH(E2.Absent_Date)  + 1

UNION ALL

SELECT  E2.Attendance _No,
        E2.Absent_Date
FROM Attendance  E1
JOIN Attendance  E2
ON E2.Attendance _No = E1.Attendance _No
AND MONTH(E2.Absent_Date)  = MONTH(E1.Absent_Date) + 1
JOIN Attendance  E3
ON E3.Attendance _No = E2.Attendance _No
AND MONTH(E3.Absent_Date) = MONTH(E2.Absent_Date)  + 1

UNION ALL

SELECT  E3.Attendance _No,
        E3.Absent_Date
FROM Attendance  E1
JOIN Attendance  E2
ON E2.Attendance _No = E1.Attendance _No
AND MONTH(E2.Absent_Date)  = MONTH(E1.Absent_Date) + 1
JOIN Attendance  E3
ON E3.Attendance _No = E2.Attendance _No
AND MONTH(E3.Absent_Date) = MONTH(E2.Absent_Date)  + 1

) A
于 2013-01-08T10:10:37.820 に答える