Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL Server:редове в колони

Моето предложение, когато работите с динамичен SQL, е винаги първо да пишете твърдо кодирана заявка, за да можете да получите правилната логика, след което да я конвертирате в динамичен SQL.

Тъй като се опитвате да завъртите 3 колони с данни, първо бих отменил завъртането на type_ds , expdt и comdt`, след което приложете функцията PIVOT.

Твърдо кодираната версия на заявката ще бъде:

SELECT  *
FROM    
(   
  select pro_id,
    type_ds = case 
                when col ='type_ds' 
                then type_ds 
                else type_ds+col end,
    value
  from
  (
     SELECT A.Pro_Id,
       c.Type_DS,
       convert(varchar(10), b.ExpDt, 120) ExpDt, 
       convert(varchar(10), b.ComDt, 120) ComDt
     FROM  dbo.Project A  
     left join [dbo].[Prj_App] B 
        on A.Pro_id = B.Pro_Id
     right outer join dbo.Approval_Type C 
        on B.App_Id = C.App_ID
   ) s
   cross apply
   (
      select 'type_ds', type_ds union all
      select 'expdt', expdt union all
      select 'comdt', comdt
   ) c (col, value)
) data
PIVOT
(   
  MAX(value)
  FOR Type_DS IN (RMC2, RMC2expdt, RMC2comdt,
                   RMC1, RMC1expdt, RMC1comdt) 
) pvt1                                        

Вижте SQL Fiddle с демонстрация . Сега, след като имате работеща версия на заявката, можете лесно да я конвертирате в динамичен SQL:

DECLARE @SQL1 NVARCHAR(MAX) = ''
DECLARE @SQL NVARCHAR(MAX) = ''

SELECT  @SQL1 = STUFF((SELECT ',' + QUOTENAME(Type_Ds) + ',' +  QUOTENAME(Type_Ds + 'ExpDt') + ',' + QUOTENAME(Type_Ds + 'ComDt')
                    from dbo.Approval_Type 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')   


SET @SQL = 'SELECT  *
            FROM    
            (   
              select pro_id,
                type_ds = case 
                            when col =''type_ds'' 
                            then type_ds 
                            else type_ds+col end,
                value
              from
              (
                 SELECT A.Pro_Id,
                   c.Type_DS,
                   convert(varchar(10), b.ExpDt, 120) ExpDt, 
                   convert(varchar(10), b.ComDt, 120) ComDt
                 FROM  dbo.Project A  
                 left join [dbo].[Prj_App] B 
                    on A.Pro_id = B.Pro_Id
                 right outer join dbo.Approval_Type C 
                    on B.App_Id = C.App_ID
               ) s
               cross apply
               (
                  select ''type_ds'', type_ds union all
                  select ''expdt'', expdt union all
                  select ''comdt'', comdt
               ) c (col, value)
           ) data
           PIVOT
           (   
              MAX(value)
              FOR Type_DS IN (' + @SQL1 + ') 
           ) pvt1 '

--print @SQL
EXECUTE SP_EXECUTESQL @SQL

Вижте SQL Fiddle с демонстрация




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ограничение на клаузата IN в Sql Server

  2. sp_generate_inserts за SQL Server 2008

  3. Незадължителни аргументи в клаузата WHERE

  4. Сблъсък на типа операнд:int е несъвместим с дата + Изявлението INSERT е в конфликт с ограничението FOREIGN KEY

  5. Ето три причини, поради които може да видите пикова активност във вашия SQL екземпляр