tag bootstrap sql-server tsql null unpivot

bootstrap - SQL Server-Incluir NULL utilizando UNPIVOT



tags jquery (7)

En algunos contextos, encontré que la izquierda se unió al resultado de UNPIVOT a la lista completa de campos, convenientemente extraída de INFORMATION_SCHEMA, como una respuesta práctica a este problema.

-- 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>

la salida se ve como

+----------------------+-----------------------+ | 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 | +----------------------+-----------------------+

UNPIVOT no devolverá NULL, pero los necesito en una consulta de comparación. Intento evitar usar ISNULL en el siguiente ejemplo (porque en el sql real hay más de 100 campos .:

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

¿Alguna alternativa?


Es un verdadero dolor. ISNULL() cambiarlos antes de UNPIVOT , ya que no hay una fila producida para que ISNULL() funcione en la generación de códigos: su amigo está aquí.

Tengo el problema en PIVOT también. Las filas que faltan se convierten en NULL , que tiene que envolver en ISNULL() toda la fila si los valores faltantes son los mismos que 0.0 por ejemplo.


ISNULL es la mitad de la respuesta. Use NULLIF para traducir de nuevo a NULL. P.ej

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;

Aquí utilizo "0Null" como mi valor intermedio. Puedes usar lo que quieras. Sin embargo, corre el riesgo de colisión con la entrada del usuario si elige algo del mundo real como "Null". La basura funciona bien "! @ # 34 ()) 0", pero puede ser más confusa para los futuros codificadores. Estoy seguro de que te haces una idea.


O, en SQLServer 2008 de forma más corta:

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


Para conservar los valores nulos, use CROSS JOIN ... CASE:

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)

En lugar de:

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

Un editor de texto con modo de columna hace que estas consultas sean más fáciles de escribir. UltraEdit lo tiene, también lo tiene Emacs. En Emacs se llama edición rectangular.

Es posible que tenga que escribirlo para 100 columnas.


Tuve el mismo problema. El uso de CROSS APPLY (SQL Server 2005 y posterior) en lugar de Unpivot resolvió el problema. Encontré la solución basada en este artículo. Un método alternativo (¿mejor?) A UNPIVOT e hice el siguiente ejemplo para demostrar que CROSS APPLY NO Unpivot NULL como 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


Usando SQL dinámico y COALESCE, resolví el problema de esta manera:

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 )