none
連続するレコードのみをまとめるSQLって組めますでしょうか? RRS feed

  • 質問

  • 元table

    ID  順序  工程 

    1   1   切る

    2   2   切る

    3   3   焼く

    4   4   切る

    5   5   煮る

    欲しいテーブル

    順序  工程

    1    切る

    2    焼く

    3    切る

    4    煮る

    上記の元テーブルのように同じ工程が連続する場合のみ、その工程をまとめ、連続しない場合は新しい順序の

    工程として表示する。

    このようなSQLは組めますでしょうか。

    ご教授の程、宜しくお願いいたします。


    • 編集済み HIRO_KU 2020年9月3日 0:21
    2020年9月3日 0:21

回答

  • 単純な GROUP BY というわけにも行かないので、
    LAG 関数を使って連続性を調査するのが良いと思います。

    WITH 例 AS (SELECT *, 継続性 = CASE
    WHEN 順序 = 1 OR 工程 <> LAG(工程, 1)
    OVER (ORDER BY 順序, ID) THEN N'新' ELSE N'続' END
    FROM 元table) SELECT 順序 = ROW_NUMBER()
    OVER (ORDER BY 順序), 工程
    FROM 例 WHERE 継続性 = N'新'
    ORDER BY 順序
    
    • 回答としてマーク HIRO_KU 2020年9月4日 14:09
    2020年9月3日 1:43
  • 一つのステートメントにこだわらなければ、以下のように実装することはできるかと。 ストアドプロシージャ化すれば、アプリケーション側からはストアドプロシージャの呼び出しのみで結果セットを取得することができるかと思います。

    create table #TempTable1 (id int IDENTITY(1,1), Seq int, Process nvarchar(50));
    declare @Id int;
    declare @Seq int;
    declare @Pro nvarchar(50);
    declare @Prob nvarchar(50);
    
    declare cur1 cursor static for select * from table1 order by ID, 順序;
    open cur1;
    fetch next from cur1 into @Id, @Seq, @Pro;
    
    while @@FETCH_STATUS = 0
    begin
    if @Prob is null or @Prob != @Pro
    begin
    	insert into #TempTable1 values(@Seq, @Pro);
    end
    
    set @Prob = @Pro;
    
    fetch next from cur1 INTO @Id, @Seq, @Pro;
    end
    
    select id as '順序', Process as '工程' from #TempTable1; 
    close cur1;
    deallocate cur1;
    drop table #TempTable1 

    • 回答としてマーク HIRO_KU 2020年9月4日 14:09
    2020年9月3日 4:36

すべての返信

  • select

    row_number() over(order by 順序) as 順序

    ,工程

    from

    (

    select max(順序) as 順序, 工程 from テーブル group by 工程

    ) as a

    でいけるような気がします。

    ーーーーーーーーーーーーーーーーー

    参考になりましたら投票と回答としてマークをお願いいたします。

    2020年9月3日 1:05
  • 単純な GROUP BY というわけにも行かないので、
    LAG 関数を使って連続性を調査するのが良いと思います。

    WITH 例 AS (SELECT *, 継続性 = CASE
    WHEN 順序 = 1 OR 工程 <> LAG(工程, 1)
    OVER (ORDER BY 順序, ID) THEN N'新' ELSE N'続' END
    FROM 元table) SELECT 順序 = ROW_NUMBER()
    OVER (ORDER BY 順序), 工程
    FROM 例 WHERE 継続性 = N'新'
    ORDER BY 順序
    
    • 回答としてマーク HIRO_KU 2020年9月4日 14:09
    2020年9月3日 1:43
  • 一つのステートメントにこだわらなければ、以下のように実装することはできるかと。 ストアドプロシージャ化すれば、アプリケーション側からはストアドプロシージャの呼び出しのみで結果セットを取得することができるかと思います。

    create table #TempTable1 (id int IDENTITY(1,1), Seq int, Process nvarchar(50));
    declare @Id int;
    declare @Seq int;
    declare @Pro nvarchar(50);
    declare @Prob nvarchar(50);
    
    declare cur1 cursor static for select * from table1 order by ID, 順序;
    open cur1;
    fetch next from cur1 into @Id, @Seq, @Pro;
    
    while @@FETCH_STATUS = 0
    begin
    if @Prob is null or @Prob != @Pro
    begin
    	insert into #TempTable1 values(@Seq, @Pro);
    end
    
    set @Prob = @Pro;
    
    fetch next from cur1 INTO @Id, @Seq, @Pro;
    end
    
    select id as '順序', Process as '工程' from #TempTable1; 
    close cur1;
    deallocate cur1;
    drop table #TempTable1 

    • 回答としてマーク HIRO_KU 2020年9月4日 14:09
    2020年9月3日 4:36
  • 他のお二人のクエリが正しそうです。こちらのクエリは無視してください!
    2020年9月3日 10:27
  • 魔界の仮面弁士様

    いつもありがとうございます。

    LAG関数は初めて知りました。

    LAGとLEADで前後のレコードを確認できるのですね。

    ぜひ試してみます。

    またよろしくお願いします。

    2020年9月4日 14:11
  • NOBTA様

    これまで単純なSQLをアプリケーション側から都度送って、結果を得ていました。

    ストアドプロシージャを使えばこういった複雑なプログラムにできるのですね。

    勉強になります。

    こちらの方法も試してみたいと思います。

    ありがとうございました。

    2020年9月4日 14:14
  • maaaaaaaa8様

    ありがとうございます。

    返信してもらえるだけでもうれしいです。

    これからもよろしくお願いします。

    2020年9月4日 14:15