2017-10-25 16 views
0

私は多くを検索しますが、私のクエリに関連するものは何も見つかりませんでした。私が探していたのは、次の行の日付を後の行に追加したいということです。例えば:私が探していたもの後ろからの値を後から入力する方法

cusnbr name loadnumber date 
1  A  10  20100101 
1  A  20  20110101 
1  B  30  20120101 * 
2  C  40  20130101 
2  D  50  20140101 * 

は出力以下のようなものです:

cusnbr name loadnumber date 
1  A  20  20120101 
2  C  40  20140101 

特定の顧客のために変更した名前に基づいて、前から*しかし、レコードの日。彼らは数百万の顧客であり、私はそれをここに入れました。どんなアプローチに従うべきか、私を助けるコードはすばらしいでしょう!

答えて

0

これはちょっと変わったクエリですが、これはあなたが探しているラインに沿っていると思いますか?

まず、私はあなたのテストデータの一時コピーを作成:

DECLARE @table TABLE (cusnbr INT, name CHAR(1), loadnumber INT, [date] DATE); 
INSERT INTO @table SELECT 1, 'A', 10, '20100101'; 
INSERT INTO @table SELECT 1, 'A', 20, '20110101'; 
INSERT INTO @table SELECT 1, 'B', 30, '20120101'; 
INSERT INTO @table SELECT 2, 'C', 40, '20130101'; 
INSERT INTO @table SELECT 2, 'D', 50, '20140101'; 

は、それから私は、顧客が名前の変更があったかを決定するためにこれを使用し、プラスあなたが必要なすべての他のメトリック:

WITH Customers AS (
    SELECT 
     cusnbr, 
     MIN(name) AS old_name, 
     MAX(name) AS new_name 
    FROM 
     @table 
    GROUP BY 
     cusnbr 
    HAVING 
     COUNT(DISTINCT name) > 1), 
LoadNumbers AS (
    SELECT 
     cusnbr, 
     name, 
     MAX(loadnumber) AS loadnumber 
    FROM 
     @table 
    GROUP BY 
     cusnbr, 
     name), 
Groups AS (
    SELECT 
     name, 
     MAX([date]) AS [date], 
     DENSE_RANK() OVER (ORDER BY name) AS id 
    FROM 
     @table 
    GROUP BY 
     name) 
SELECT 
    c.cusnbr, 
    c.old_name, 
    c.new_name, 
    l.loadnumber, 
    g2.[date] 
FROM 
    Customers c 
    INNER JOIN Groups g1 ON g1.name = c.old_name 
    INNER JOIN Groups g2 ON g2.id = g1.id + 1 
    INNER JOIN LoadNumbers l ON l.cusnbr = c.cusnbr AND l.name = c.old_name; 

結果は以下のとおりです。

cusnbr old_name new_name loadnumber date 
1  A   B   20   2012-01-01 
2  C   D   40   2014-01-01 

私はFOLし、これは簡単にするために、新しい/古い名前を追加しました低いですが、必要のないものを取り除くことはできますか?

関連する問題