0

従業員のタイムスタンプ付きアクション レコードを含むテーブルがあります。各レコードには、部門と役職があります。ここで、従業員が部署や役職を変更したときに発生した変更を抽出したいと考えています。

SQL Server 2008 を使用しています。

テーブルが単純な従業員のレコードを保持していると仮定すると、データは次のようになります。

Time |  Department | WorkTitle
t1        Dep1         Wt1    <---
t2        Dep1         Wt1
t3        Dep2         Wt2    <---
t4        Dep2         Wt2
t5        Dep1         Wt1    <---
t6        Dep3         Wt1    <---
t7        Dep3         Wt1
t8        Dep3         Wt1

従業員が新しい部署に現れたとき、および/または新しい役職に就いたときの最初のインスタンスを抽出したいと考えています。

上記のデータでは、矢印の付いたレコードが抽出されたものであり、次の結果になるはずです。

Time |  Department | WorkTitle
t1        Dep1         Wt1
t3        Dep2         Wt2
t5        Dep1         Wt1
t6        Dep3         Wt1

時刻 t1 と t5 では同じ部門と役職が発生するため、単純な GROUP BY 句は機能しないことに注意してください。

OVER/PARTITION を使用していくつかの試みを試みましたが、このクエリの複雑さは私の知識を超えているようです。

これは SQL ステートメントを使用して行うことができますか?

4

3 に答える 3

2

Gordon Linoff が言ったように、この問題は、lag()関数があれば非常に簡単です。SQL Server 2008 にはそれがないため、outer applyで解決することを好みます。

select t1.*
from t as t1
    outer apply (
        select top 1 t2.*
        from t as t2
        where t2.worktime < t1.worktime
        order by t2.worktime desc
    ) as t2
where
    t2.worktime is null or
    t2.department <> t1.department or
    t2.worktitle <> t1.worktitle
于 2013-08-19T16:06:46.343 に答える
0

この非三角結合ソリューションを試すことができます。

DECLARE @MyTable TABLE(
    -- You should use appropiate data types for every column
    [Time]      VARCHAR(20) NOT NULL,
    Department  VARCHAR(20) NOT NULL,
    WorkTitle   VARCHAR(20) NOT NULL
);

INSERT INTO @MyTable ([Time],Department,WorkTitle)
SELECT 't1', 'Dep1', 'Wt1'
UNION ALL SELECT 't2', 'Dep1', 'Wt1'
UNION ALL SELECT 't3', 'Dep2', 'Wt2'
UNION ALL SELECT 't4', 'Dep2', 'Wt2'
UNION ALL SELECT 't5', 'Dep1', 'Wt1'
UNION ALL SELECT 't6', 'Dep3', 'Wt1'
UNION ALL SELECT 't7', 'Dep3', 'Wt1'
UNION ALL SELECT 't8', 'Dep3', 'Wt1';

DECLARE @ResultsWithRowNum TABLE
(
    RowNum      INT PRIMARY KEY,
    [Time]      VARCHAR(20) NOT NULL,
    Department  VARCHAR(20) NOT NULL,
    WorkTitle   VARCHAR(20) NOT NULL
);
INSERT  @ResultsWithRowNum(RowNum,[Time],Department,WorkTitle)
SELECT  ROW_NUMBER() OVER(ORDER BY x.[Time]) AS RowNum,x.[Time],x.Department,x.WorkTitle
FROM    @MyTable x;

WITH RecursiveCTE
AS
(
    SELECT  crt.RowNum,
            crt.[Time],
            crt.Department,
            crt.WorkTitle,
            1 AS IsFirstRowNewGroup
    FROM    @ResultsWithRowNum crt
    WHERE   crt.RowNum=1
    UNION ALL
    SELECT  crt.RowNum,
            crt.[Time],
            crt.Department,
            crt.WorkTitle,
            CASE WHEN prev.Department = crt.Department AND prev.WorkTitle = crt.WorkTitle THEN 0 ELSE 1 END
    FROM    @ResultsWithRowNum crt
    INNER JOIN RecursiveCTE prev ON crt.RowNum = prev.RowNum + 1
)
SELECT  *
FROM    RecursiveCTE rec
WHERE   rec.IsFirstRowNewGroup = 1
OPTION (MAXRECURSION 0);

結果:

RowNum Time Department WorkTitle IsFirstRowNewGroup
------ ---- ---------- --------- ------------------
1      t1   Dep1       Wt1       1
3      t3   Dep2       Wt2       1
5      t5   Dep1       Wt1       1
6      t6   Dep3       Wt1       1
于 2013-08-19T16:47:42.663 に答える