복붙노트

[SQL] 동적으로 열 SQL을 생성

SQL

동적으로 열 SQL을 생성

나는 고객의 테이블이

Customer ID        Name         
   1               John        
   2               Lewis        
   3               Mary         

나는 다른 테이블의 고객 보상이

 TypeID           Description
   1                Bronze
   2                Silver
   3                Gold
   4               Platinum
   5               AnotherOne

그리고 최종 테이블

 RewardID          TypeID          CustomerID
    1                1                 1
    2                1                 1
    3                2                 1
    4                2                 2

customerTypes 테이블은 동적이며, 이러한 형태의 많은 추가 및 제거 할 수있다. 기본적으로 모든 I의 희망은 동적으로 생성되는 열과 각 카운트, 같은 것입니다

CustomerName        Bronze        Silver     Gold      Platinum     AnotherOne    total
   John               2             1         0           0             0           3
   Lewis              0             1         0           0             0           1
 Grand TOTAL          2             2         0           0             0           4

I와 같은 문제는 유형이 동적이며 나는 시스템의 종류에 따라 동적으로 열을 필요로하므로 고객이 동적된다는 사실을 말했다

내가있는 DataGridView이 필요로 나는 # c를 태그 한

미리 감사드립니다

해결법

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

    1.당신은 이것에 대한 PIVOT 기능을 사용하는 것이 좋습니다. 당신이 열 알려진 번호가있는 경우에, 당신은 하드 코드 값을 할 수 있습니다

    당신은 이것에 대한 PIVOT 기능을 사용하는 것이 좋습니다. 당신이 열 알려진 번호가있는 경우에, 당신은 하드 코드 값을 할 수 있습니다

    select name, [Bronze], [Silver], [Gold], [Platinum], [AnotherOne]
    from
    (
      select c.name,
        cr.description,
        r.typeid
      from customers c
      left join rewards r
        on c.id = r.customerid
      left join customerrewards cr
        on r.typeid = cr.typeid
    ) x
    pivot
    (
      count(typeid)
      for description in ([Bronze], [Silver], [Gold], [Platinum], [AnotherOne])
    ) p;
    

    데모와 SQL 바이올린을 참조하십시오.

    당신이 열을 알 수없는 번호가있는 경우 지금, 당신은 PIVOT 동적 SQL을 사용할 수 있습니다 :

    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT ',' + QUOTENAME(description) 
                        from customerrewards
                        group by description, typeid
                        order by typeid
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = 'SELECT name,' + @cols + ' from 
                 (
                    select c.name,
                      cr.description,
                      r.typeid
                    from customers c
                    left join rewards r
                      on c.id = r.customerid
                    left join customerrewards cr
                      on r.typeid = cr.typeid
                ) x
                pivot 
                (
                    count(typeid)
                    for description in (' + @cols + ')
                ) p '
    
    execute(@query)
    

    SQL 바이올린 함께 데모를 참조하십시오

    당신은 전체 열을 포함해야하는 경우에, 당신은 ROLLUP (정적 버전 데모)를 사용할 수 있습니다 :

    select name, sum([Bronze]) Bronze, sum([Silver]) Silver, 
      sum([Gold]) Gold, sum([Platinum]) Platinum, sum([AnotherOne]) AnotherOne
    from 
    (
      select name, [Bronze], [Silver], [Gold], [Platinum], [AnotherOne]
      from
      (
        select c.name,
          cr.description,
          r.typeid
        from customers c
        left join rewards r
          on c.id = r.customerid
        left join customerrewards cr
          on r.typeid = cr.typeid
      ) x
      pivot
      (
        count(typeid)
        for description in ([Bronze], [Silver], [Gold], [Platinum], [AnotherOne])
      ) p
    ) x
    group by name with rollup
    

    동적 버전 (데모) :

    DECLARE @cols AS NVARCHAR(MAX),
        @colsRollup AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT ',' + QUOTENAME(description) 
                        from customerrewards
                        group by description, typeid
                        order by typeid
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    select @colsRollup 
          = STUFF((SELECT ', Sum(' + QUOTENAME(description) + ') as '+ QUOTENAME(description)
                        from customerrewards
                        group by description, typeid
                        order by typeid
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    
    set @query 
              = 'SELECT name, '+ @colsRollup + '
                 FROM
                 (
                    SELECT name,' + @cols + ' from 
                     (
                        select c.name,
                          cr.description,
                          r.typeid
                        from customers c
                        left join rewards r
                          on c.id = r.customerid
                        left join customerrewards cr
                          on r.typeid = cr.typeid
                    ) x
                    pivot 
                    (
                        count(typeid)
                        for description in (' + @cols + ')
                    ) p 
                  ) x1
                  GROUP BY name with ROLLUP'
    
    execute(@query)
    
  2. from https://stackoverflow.com/questions/12643117/dynamically-create-columns-sql by cc-by-sa and MIT license