복붙노트

[SQL] 동일한 ID를 갖는 행 테이블에서 컬럼을 사용하여 문자열 값을 형성하는 가장 좋은 방법이 무엇입니까?

SQL

동일한 ID를 갖는 행 테이블에서 컬럼을 사용하여 문자열 값을 형성하는 가장 좋은 방법이 무엇입니까?

나는 SQL Server 2008을 사용하고 있습니다.

이것은 내 테이블입니다.

표 A

 Aid int pk
 col2
 col3
 XYZID int

표 B

 Bid int pk
 XYZID int
 Col2
 Col3 
 Col4
 seq -- (Sequence )

표 B는 다음과 같이 될 것이다

seq   col2    |XYZID|Bid |col3| col4 
===============================================
  1   foo     | 1   |  1 | 12 | wqw
  3   bar     | 1   | 10 | 77 | kikk
  2   foobar  | 1   |  2 |  w | ed
  1   barfoo  | 2   |  4 |  e | dwe
  2   asdsad  | 2   |  5 |  e | e 

표 A는 메인 테이블과의 XYZID에 기초

나는 XYZID 서열과 TableB의에서 안부를 사용하여 문자열 값을 생성해야합니다.

나는 XYZID 서열과 TableB의에서 안부를 사용하여 문자열 값을 생성해야합니다.

예를 들어 : xyzid = 1

내가 기대 : foo는-12 wqw #는 foobar-w-ED # 바 - 77 kikk

순서에 따라 foo는-1,는 foobar-2, 바-3

해결법

  1. ==============================

    1.XYZID = 1.

    XYZID = 1.

    select stuff((select '#'+col2+'-'+col3+'-'+col4
                  from TableB
                  where XYZID = 1
                  order by seq
                  for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')
    

    타블로의 모든 행의 경우 :

    select stuff((select '#'+col2+'-'+col3+'-'+col4
                  from TableB as B
                  where A.XYZID = B.XYZID
                  order by seq
                  for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')
    from TableA as A
    
  2. ==============================

    2.DDL :

    DDL :

    drop table tblx;
    create table tblx
    (
    seq int,
    col2 varchar(50),
    xyzid int,
    bid int,
    col3 varchar(50),
    col4 varchar(50)
    );
    

    데이터:

    insert into tblx(seq,col2,xyzid,bid,col3,col4) values
    (1,   'foo'     , 1,   1,  '12', 'wqw'),
    (3,   'bar'     , 1,   10, '77', 'kikk'),
    (2,   'foobar'  , 1,   2,  'w',  'ed'),
    (1,   'barfoo'  , 2,   4,  'e',  'dwe'),
    (2,   'asdsad'  , 2,   5,  'e',  'e');
    

    CTE 접근 방식을 사용 :

    with a(xyzid, seq, x) as
    (
    select xyzid, seq, cast(col2 + '-' + col3 + '-' + col4 as varchar(max)) as x
    from tblx
    where seq = 1
    union all
    select t.xyzid, t.seq, a.x + '#' + (t.col2 + '-' + t.col3 + '-' + t.col4)
    from tblx t
    join a on a.xyzid = t.xyzid and t.seq = a.seq + 1
    )
    select xyzid, rtrim(x) as x 
    from a w
    where seq = (select MAX(seq) from a where xyzid = w.xyzid)
    order by xyzid;
    

    산출:

    xyzid       x
    ----------- -----------------------------------
    1           foo-12-wqw#foobar-w-ed#bar-77-kikk
    2           barfoo-e-dwe#asdsad-e-e
    
    (2 row(s) affected)
    

    기본 테이블 (예를 들어, 테이블 A)를 사용하면 단지 쿼리의 간단한 수정이 필요합니다 :

    with a(xyzid, seq, x) as
    (
    select xyzid, seq, cast(col2 + '-' + col3 + '-' + col4 as varchar(max)) as x
    from tblx
    where seq = 1
    union all
    select t.xyzid, t.seq, a.x + '#' + (col2 + '-' + col3 + '-' + col4)
    from tblx t
    join a on a.xyzid = t.xyzid and t.seq = a.seq + 1
    )
    select w.xyzid, rtrim(x) as x 
    from tblA w -- just add this main table
    left join a on a.xyzid = w.xyzid 
                   and seq = (select MAX(seq) from a where xyzid = w.xyzid)
    order by xyzid;
    

    데이터:

    create table tblA
    (
    aid int identity(1,1) primary key,
    col2 varchar(50),
    col3 varchar(50),
    xyzid int
    );
    
    
    insert into tblA(col2,col3,xyzid) values
    ('','',1),
    ('','',2),
    ('','',3);
    

    산출:

    xyzid       x
    ----------- ------------------------------------
    1           foo-12-wqw#foobar-w-ed#bar-77-kikk
    2           barfoo-e-dwe#asdsad-e-e
    3           NULL
    
    (3 row(s) affected)
    

    SEQ 필드가 비 연속적인 및 / 또는 고유하지 않은 경우, 시퀀서를 넣어 :

    with sequencer as
    (
    select 
        xyzid, ROW_NUMBER() over(partition by xyzid order by seq) as seq
        , col2, col3, col4 
    from tblx 
    )
    ,a(xyzid, seq, x) as
    (
    select xyzid, seq, cast(col2 + '-' + col3 + '-' + col4 as varchar(max)) as x
    from sequencer
    where seq = 1
    union all
    select t.xyzid, t.seq, a.x + '#' + (col2 + '-' + col3 + '-' + col4)
    from sequencer t
    join a on a.xyzid = t.xyzid and t.seq = a.seq + 1
    )
    select w.xyzid, rtrim(x) as x 
    from tblA w
    left join a on a.xyzid = w.xyzid 
                and seq = (select MAX(seq) from a where xyzid = w.xyzid)
    order by xyzid;
    

    샘플 비 연속적인 서열 :

    insert into tblx(seq,col2,xyzid,bid,col3,col4) values
    (1,   'foo'     , 1,   1,  '12', 'wqw'),
    (5,   'bar'     , 1,   10, '77', 'kikk'),
    (3,   'foobar'  , 1,   2,  'w',  'ed'),
    (1,   'barfoo'  , 2,   4,  'e',  'dwe'),
    (3,   'asdsad'  , 2,   5,  'e',  'e');
    

    (여전히 같은) 출력 :

    xyzid       x
    ----------- --------------------------------------
    1           foo-12-wqw#foobar-w-ed#bar-77-kikk
    2           barfoo-e-dwe#asdsad-e-e
    3           NULL
    
    (3 row(s) affected)
    

    속도에 관해서는, 그것은 빠른 여전히. CTE 쿼리 비용은 95 %이다 XML 접근 방식에 대한 5 %입니다

  3. from https://stackoverflow.com/questions/11137075/which-is-the-best-way-to-form-the-string-value-using-column-from-a-table-with-ro by cc-by-sa and MIT license