문제

Unpivot은 NULLS를 반환하지 않지만 비교 쿼리에서 필요합니다. ISNULL을 사용하지 않으려 고합니다. 다음 예제 (실제 SQL에는 100 개가 넘는 필드가 있기 때문에. : : : : : : : 100 개 이상의 필드가 있기 때문입니다. :

Select ID, theValue, column_name
From 
(select ID,
  ISNULL(CAST([TheColumnToCompare]  AS VarChar(1000)), '') as TheColumnToCompare
  from MyView
  where The_Date = '04/30/2009'
) MA
UNPIVOT
   (theValue FOR column_name IN 
   ([TheColumnToCompare])
) AS unpvt

대안이 있습니까?

도움이 되었습니까?

해결책

진짜 고통입니다. 당신은 앞에 그들을 꺼내야합니다 UNPIVOT, 행이 없기 때문에 ISNULL() On -Code Generation은 여기에서 친구입니다.

나는 문제가있다 PIVOT 또한. 누락 된 줄이 바뀝니다 NULL, 당신은 포장해야합니다 ISNULL() 결 측값이 동일하다면 행을 가로 질러 모든 방향으로 0.0 예를 들어.

다른 팁

널 보존하려면 크로스 조인을 사용하십시오 ... 케이스 :

select a.ID, b.column_name
, column_value = 
    case b.column_name
      when 'col1' then a.col1
      when 'col2' then a.col2
      when 'col3' then a.col3
      when 'col4' then a.col4
    end
from (
  select ID, col1, col2, col3, col4 
  from table1
  ) a
cross join (
  select 'col1' union all
  select 'col2' union all
  select 'col3' union all
  select 'col4'
  ) b (column_name)

대신에:

select ID, column_name, column_value
From (
  select ID, col1, col2, col3, col4
  from from table1
  ) a
unpivot (
  column_value FOR column_name IN (
    col1, col2, col3, col4)
  ) b

열 모드가있는 텍스트 편집기는 이러한 쿼리를 쉽게 쓸 수 있도록합니다. Ultraedit에는 EMAC도 있습니다. EMAC에서는 직사각형 편집이라고합니다.

100 개의 열에 대해 스크립트해야 할 수도 있습니다.

나는 같은 문제에 부딪쳤다. 사용 CROSS APPLY 대신 (SQL Server 2005 이상) Unpivot 문제를 해결했습니다. 이 기사를 기반으로 솔루션을 찾았습니다 대안 (더 나은?) 방법을 해제하는 방법그리고 나는 Cross Apply가 널을 무시하지 않을 것임을 입증하기 위해 다음 예를 만들었습니다. Unpivot.

create table #Orders (OrderDate datetime, product nvarchar(100), ItemsCount float, GrossAmount float, employee nvarchar(100))

 insert into #Orders
 select getutcdate(),'Windows',10,10.32,'Me'
 union 
 select getutcdate(),'Office',31,21.23,'you'
 union 
 select getutcdate(),'Office',31,55.45,'me'
 union  
 select getutcdate(),'Windows',10,null,'You'

SELECT OrderDate, product,employee,Measure,MeasureType
 from #Orders orders
 CROSS APPLY (
    VALUES ('ItemsCount',ItemsCount),('GrossAmount',GrossAmount)
    ) 
    x(MeasureType, Measure) 


SELECT OrderDate, product,employee,Measure,MeasureType
from #Orders orders
UNPIVOT
   (Measure FOR MeasureType IN 
      (ItemsCount,GrossAmount)
)AS unpvt;


 drop table #Orders

또는 SQLSERVER 2008에서 짧은 방법으로 :

...
cross join 
(values('col1'), ('col2'), ('col3'), ('col4')) column_names(column_name)

나는 왼쪽 외부의 결합되지 않은 결과를 발견하지 못했다.

-- test data
CREATE TABLE _t1(name varchar(20),object_id varchar(20),principal_id varchar(20),schema_id varchar(20),parent_object_id varchar(20),type varchar(20),type_desc varchar(20),create_date varchar(20),modify_date varchar(20),is_ms_shipped varchar(20),is_published varchar(20),is_schema_published varchar(20))
INSERT INTO _t1 SELECT 'blah1', 3, NULL, 4, 0, 'blah2', 'blah3', '20100402 16:59:23.267', NULL, 1, 0, 0 

-- example
select c.COLUMN_NAME, Value
from INFORMATION_SCHEMA.COLUMNS c
left join (
  select * from _t1
) q1
unpivot (Value for COLUMN_NAME in (name,object_id,principal_id,schema_id,parent_object_id,type,type_desc,create_date,modify_date,is_ms_shipped,is_published,is_schema_published)
) t on t.COLUMN_NAME = c.COLUMN_NAME
where c.TABLE_NAME = '_t1'
</pre>

출력은 다음과 같습니다.

+----------------------+-----------------------+
|    COLUMN_NAME       |        Value          |
+----------------------+-----------------------+
| name                 | blah1                 |
| object_id            | 3                     |
| principal_id         | NULL                  | <======
| schema_id            | 4                     |
| parent_object_id     | 0                     |
| type                 | blah2                 |
| type_desc            | blah3                 |
| create_date          | 20100402 16:59:23.26  |
| modify_date          | NULL                  | <======
| is_ms_shipped        | 1                     |
| is_published         | 0                     |
| is_schema_published  | 0                     |
+----------------------+-----------------------+
    

동적 SQL과 Coalesce를 사용하여 다음과 같은 문제를 해결했습니다.

DECLARE @SQL NVARCHAR(MAX)
DECLARE @cols NVARCHAR(MAX)
DECLARE @dataCols NVARCHAR(MAX)

SELECT 
    @dataCols = COALESCE(@dataCols + ', ' + 'ISNULL(' + Name + ',0) ' + Name , 'ISNULL(' + Name + ',0) ' + Name )
FROM Metric WITH (NOLOCK)
ORDER BY ID

SELECT 
    @cols = COALESCE(@cols + ', ' + Name , Name )
FROM Metric WITH (NOLOCK)
ORDER BY ID

SET @SQL = 'SELECT ArchiveID, MetricDate, BoxID, GroupID, ID MetricID, MetricName, Value
            FROM 
               (SELECT ArchiveID, [Date] MetricDate, BoxID, GroupID,  ' + @dataCols + '
                FROM MetricData WITH (NOLOCK)
                INNER JOIN Archive WITH (NOLOCK)
                    ON ArchiveID = ID
                WHERE BoxID = ' + CONVERT(VARCHAR(40), @BoxID) + '
                AND GroupID = ' + CONVERT(VARCHAR(40), @GroupID) + ') p
            UNPIVOT
               (Value FOR MetricName IN 
                  (' + @cols + ')
            )AS unpvt
            INNER JOIN Metric WITH (NOLOCK)
                ON MetricName  = Name
            ORDER BY MetricID, MetricDate'

EXECUTE( @SQL )

ISNULL은 답의 절반입니다. Nullif를 사용하여 NULL로 다시 번역하십시오. 예를 들어

DECLARE @temp TABLE(
    Foo varchar(50),
    Bar varchar(50) NULL
    );

INSERT INTO @temp( Foo,Bar )VALUES( 'licious',NULL );

SELECT * FROM @temp;

SELECT 
    Col,
    NULLIF( Val,'0Null' ) AS Val 
FROM(
    SELECT
        Foo,
        ISNULL( Bar,'0Null' ) AS Bar
    FROM
        @temp
    ) AS t
UNPIVOT(
    Val FOR Col IN(
        Foo,
        Bar 
        )
    ) up;

여기서는 "0Null"을 내 중간 값으로 사용합니다. 당신은 당신이 좋아하는 것을 사용할 수 있습니다. 그러나 "null"과 같은 실제를 선택하면 사용자 입력과 충돌 할 위험이 있습니다. 쓰레기는 잘 작동합니다. "@#34 ()) 0"이지만 미래의 코더에게 더 혼란 스러울 수 있습니다. 나는 당신이 사진을 얻을 것이라고 확신합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top