3

SQL Server 2008 R2 を使用しており、次のデータセットがあります。

+---------+--------------+--------------+----------+------------+------------+
| Dossier | refmouvement | refadmission | refunite |  datedeb   |  datefin   |
+---------+--------------+--------------+----------+------------+------------+
| P001234 |         2567 |         1234 |      227 | 2012-01-01 | 2012-01-02 |
| P001234 |         2568 |         1234 |      227 | 2012-01-02 | 2012-01-03 |
| P001234 |         2569 |         1234 |      224 | 2012-01-03 | 2012-01-06 |
| P001234 |         2570 |         1234 |      232 | 2012-01-06 | 2012-01-10 |
| P001234 |         2571 |         1234 |      232 | 2012-01-10 | 2012-01-15 |
| P001234 |         2572 |         1234 |      232 | 2012-01-15 | 2012-01-20 |
| P001234 |         2573 |         1234 |      232 | 2012-01-20 | 2012-01-25 |
| P001234 |         2574 |         1234 |      224 | 2012-01-25 | 2012-01-29 |
| P001234 |         2575 |         1234 |      227 | 2012-01-29 | 2012-02-05 |
| P001234 |         2576 |         1234 |      227 | 2012-02-05 | 2012-02-10 |
| P001234 |         2577 |         1234 |      232 | 2012-02-10 | 2012-02-15 |
| P001234 |         2578 |         1234 |      201 | 2012-02-15 | 2012-02-26 |
+---------+--------------+--------------+----------+------------+------------+

このデータセットの順序はdatedeb、別名startdateです。

datefinお気づきのように、これは次の行と等しい連続したデータセットですdatedeb

次のような列IDに基づいて一意の ID を与える列refuniteを作成する必要があります。datedeb

+----+---------+--------------+--------------+----------+------------+------------+
| ID | Dossier | refmouvement | refadmission | refunite |  datedeb   |  datefin   |
+----+---------+--------------+--------------+----------+------------+------------+
|  1 | P001234 |         2567 |         1234 |      227 | 2012-01-01 | 2012-01-02 |
|  1 | P001234 |         2568 |         1234 |      227 | 2012-01-02 | 2012-01-03 |
|  2 | P001234 |         2569 |         1234 |      224 | 2012-01-03 | 2012-01-06 |
|  3 | P001234 |         2570 |         1234 |      232 | 2012-01-06 | 2012-01-10 |
|  3 | P001234 |         2571 |         1234 |      232 | 2012-01-10 | 2012-01-15 |
|  3 | P001234 |         2572 |         1234 |      232 | 2012-01-15 | 2012-01-20 |
|  3 | P001234 |         2573 |         1234 |      232 | 2012-01-20 | 2012-01-25 |
|  4 | P001234 |         2574 |         1234 |      224 | 2012-01-25 | 2012-01-29 |
|  5 | P001234 |         2575 |         1234 |      227 | 2012-01-29 | 2012-02-05 |
|  5 | P001234 |         2576 |         1234 |      227 | 2012-02-05 | 2012-02-10 |
|  6 | P001234 |         2577 |         1234 |      232 | 2012-02-10 | 2012-02-15 |
|  7 | P001234 |         2578 |         1234 |      201 | 2012-02-15 | 2012-02-26 |
+----+---------+--------------+--------------+----------+------------+------------+

RANK()ROW_NUMBER()または関数、またはその組み合わせでこれを達成できることに頭を包むことはDENSE_RANK()できません。どこでも見ましたが、何も見つかりません。適切なキーワードを使用していない可能性がありますが、それを理解することはできません

どんな助けでも大歓迎です

ありがとう。

これまでに試したコードは次のとおりです。

SELECT 
   ROW_NUMBER() over(order by t1.[datedeb])  as [ID1],
   dense_Rank() over(partition by t1.[refunite]   order by t1.[datedeb])  as [ID2],
   t1.[Dossier]
   ,t1.[refmouvement]
   ,t1.[refadmission]
   ,t1.[refunite]
   ,t1.[datedeb]
   ,t1.[datefin]
   ,t2.[refmouvement] as [prev_refmouvement]
   ,t2.refunite as prev_refunite
FROM [sometable] t1
LEFT OUTER JOIN [sometable] t2  /*self join*/
     ON t2.datefin = t1.datedeb
        AND t1.[refadmission] = t2.[refadmission]
ORDER BY
   t1.[datedeb]

これが私に与えるものです:

+-----+-----+---------+--------------+--------------+----------+------------+------------+-------------------+---------------+
| ID1 | ID2 | Dossier | refmouvement | refadmission | refunite |  datedeb   |  datefin   | prev_refmouvement | prev_refunite |
+-----+-----+---------+--------------+--------------+----------+------------+------------+-------------------+---------------+
|   1 |   1 | P001234 |         2567 |         1234 |      227 | 2012-01-01 | 2012-01-02 | NULL              | NULL          |
|   2 |   2 | P001234 |         2568 |         1234 |      227 | 2012-01-02 | 2012-01-03 | 2567              | 227           |
|   3 |   1 | P001234 |         2569 |         1234 |      224 | 2012-01-03 | 2012-01-06 | 2568              | 227           |
|   4 |   1 | P001234 |         2570 |         1234 |      232 | 2012-01-06 | 2012-01-10 | 2569              | 224           |
|   5 |   2 | P001234 |         2571 |         1234 |      232 | 2012-01-10 | 2012-01-15 | 2570              | 232           |
|   6 |   3 | P001234 |         2572 |         1234 |      232 | 2012-01-15 | 2012-01-20 | 2571              | 232           |
|   7 |   4 | P001234 |         2573 |         1234 |      232 | 2012-01-20 | 2012-01-25 | 2572              | 232           |
|   8 |   2 | P001234 |         2574 |         1234 |      224 | 2012-01-25 | 2012-01-29 | 2573              | 232           |
|   9 |   3 | P001234 |         2575 |         1234 |      227 | 2012-01-29 | 2012-02-05 | 2574              | 224           |
|  10 |   4 | P001234 |         2576 |         1234 |      227 | 2012-02-05 | 2012-02-10 | 2575              | 227           |
|  11 |   5 | P001234 |         2577 |         1234 |      232 | 2012-02-10 | 2012-02-15 | 2576              | 227           |
|  12 |   1 | P001234 |         2578 |         1234 |      201 | 2012-02-15 | 2012-02-26 | 2577              | 232           |
+-----+-----+---------+--------------+--------------+----------+------------+------------+-------------------+---------------+

シャズ

4

3 に答える 3

2

もちろん、テーブル変数を削除して、WITH に複数のテーブルを含めることもできます。Bogdan Sahleans の回答に基づいて、次のように書き換えることができます。

WITH CTEHelper AS 
    (SELECT ROW_NUMBER() OVER(ORDER BY datedeb) AS RowNum,
            refunite, 
            datedeb
    FROM    dbo.Sometable),
CTERecursive AS (
        SELECT  crt.RowNum,
                crt.refunite,
                crt.datedeb,
                1 AS Id -- Starting rank
        FROM    CTEHelper crt
        WHERE   crt.RowNum = 1
        UNION ALL
        SELECT  crt.RowNum,
                crt.refunite,
                crt.datedeb,
                CASE WHEN prev.refunite = crt.refunite THEN prev.Id ELSE prev.Id + 1 END
        FROM    CTEHelper crt INNER JOIN CTERecursive prev ON crt.RowNum = prev.RowNum + 1
    )
SELECT  crt.id, 
        s.*
FROM    CTERecursive crt
    JOIN Sometable s ON s.refunite = crt.refunite AND s.datedeb = crt.datedeb
于 2013-04-21T12:07:32.553 に答える
1
with sometable as (
    select *
    from (
        values ('P001234', 2567, 1234, 227, cast('2012-01-01' as date), cast('2012-01-02' as date)),
        ('P001234', 2568, 1234, 227, cast('2012-01-02' as date), cast('2012-01-03' as date)),
        ('P001234', 2569, 1234, 224, cast('2012-01-03' as date), cast('2012-01-06' as date)),
        ('P001234', 2570, 1234, 232, cast('2012-01-06' as date), cast('2012-01-10' as date)),
        ('P001234', 2571, 1234, 232, cast('2012-01-10' as date), cast('2012-01-15' as date)),
        ('P001234', 2572, 1234, 232, cast('2012-01-15' as date), cast('2012-01-20' as date)),
        ('P001234', 2573, 1234, 232, cast('2012-01-20' as date), cast('2012-01-25' as date)),
        ('P001234', 2574, 1234, 224, cast('2012-01-25' as date), cast('2012-01-29' as date)),
        ('P001234', 2575, 1234, 227, cast('2012-01-29' as date), cast('2012-02-05' as date)),
        ('P001234', 2576, 1234, 227, cast('2012-02-05' as date), cast('2012-02-10' as date)),
        ('P001234', 2577, 1234, 232, cast('2012-02-10' as date), cast('2012-02-15' as date)),
        ('P001234', 2578, 1234, 201, cast('2012-02-15' as date), cast('2012-02-26' as date))
    ) t (Dossier, refmouvement, refadmission, refunite, datedeb, datefin)
), pos as (
    select d.*, (case when d2.refunite is null then null 
                        when d2.refunite != d.refunite then d2.datedeb 
                        else d.datedeb end) as forward, 
                (case when d3.refunite is null then null 
                        when d3.refunite != d.refunite then d3.datedeb 
                        else d.datedeb end) as backward
    from sometable d
    left outer join sometable d2 on d.refadmission = d2.refadmission and d.datefin = d2.datedeb
    left outer join sometable d3 on d.refadmission = d3.refadmission and d.datedeb = d3.datefin
)
select dense_rank() over (order by isnull((select min(datedeb) 
                                            from pos 
                                            where refadmission = t.refadmission 
                                            and refunite = t.refunite 
                                            and datedeb > t.datedeb 
                                            and datedeb = backward
                                            and ((t.datedeb = t.backward and t.datedeb = t.forward) 
                                                    or t.datedeb != t.backward or t.backward is null)
                                            and datedeb != forward), datedeb)) as ID, 
       Dossier, refmouvement, refadmission, refunite, datedeb, datefin
from pos t
order by datedeb
于 2013-04-21T14:15:52.790 に答える