2010-05-24 22 views
5

He configurado una vista que combina todos los datos en varias tablas. ¿Hay alguna manera de escribir esto para que solo se muestren las columnas que contienen datos no nulos y las columnas que contienen todos los valores NULL no estén incluidas?Cómo no mostrar columnas que son NULL en una vista

AGREGADO: Lo siento, todavía estoy estudiando y trabajando en mi primer gran proyecto, así que cada día parece ser una nueva experiencia en el minuto. No he sido muy claro, y eso se debe en parte a que no estoy seguro de estar haciendo las cosas correctamente. El cliente es una biblioteca académica y la base de datos registra detalles de colecciones específicas. La vista que mencioné es para mostrar todos los datos almacenados sobre un elemento, por lo que reúne tablas sobre publicación, copia, autor, editorial, idioma, etc. Un pequeño número de artículos en la colección son documentos, por lo que tienen detalles adicionales además de los detalles bibliográficos estándar. Lo que no quería era que un usuario obtuviera todos los campos vacíos relacionados con los documentos, si lo que se devolvía solo constaba de libros, por lo tanto, los campos de la tabla de papel eran todos nulos. Entonces pensé que tal vez habría una manera de no mostrar esto. Alguien ha comentado que este es el trabajo de la aplicación cliente en lugar de la base de datos en sí, así que puedo dejar esto hasta que llegue a esa fase del proyecto.

+1

que parece propenso a leer datos tabulares incorrectamente, si el formato cambia dependiendo del contenido ... –

+3

Entonces, si la columna A para el registro 1 tiene un valor, pero el valor de la columna A del registro A es NULL - debería ser visible en el ¿ver? –

+0

Esto suena como lógica que debería estar en la GUI, no en la base de datos. Esto no cumpliría con un contrato de recuperación de base de datos adecuado, ya que el diseño podría cambiar en cualquier momento. – cjk

Respuesta

1
CREATE VIEW dbo.YourView 
AS 
    SELECT (list of fields) 
    FROM dbo.Table1 t1 
    INNER JOIN dbo.Table2 t2 ON t1.ID = t2.FK_ID 
    WHERE t1.SomeColumn IS NOT NULL 
    AND t2.SomeOtherColumn IS NOT NULL 

En su definición de la vista, se pueden incluir condiciones en las que se puede excluir filas que tienen ciertas columnas que son NULL.

Actualización: realmente no se puede filtrar las columnas - se define la lista de columnas que forman parte de la vista en su definición de la vista, y esta lista es fijo y no puede ser cambiado dinámicamente ......

Lo que podrías hacer es una construcción ISNULL(column, '') para reemplazar esos valores NULL con una cadena vacía. O bien, necesita manejar excluyendo esas columnas en la interfaz de su pantalla, no en la definición de la vista SQL ...

Lo único que veo que puede hacer es asegurarse de seleccionar solo aquellas columnas de la vista que usted sabe que no son NULL:

SELECT (list of non-null fields) FROM dbo.YourView 
WHERE (column1 IS NOT NULL) 

y así sucesivamente - pero no hay manera simple o mágica para seleccionar todas las columnas que no son NULL en una instrucción SELECT ...

+0

¿Eso es lo que el cartel está pidiendo? –

+1

Esto filtrará todas las filas que contengan valores nulos en ciertas columnas, lo cual es ligeramente diferente de lo que creo que es el poster. – Justin

+0

Una solicitud bastante extraña, pero ustedes parecen tener razón ... mmm ... no se puede pensar en ninguna forma de lograr eso ... al menos no en el nivel SQL ... o tal vez sea solo una desafortunada elección de palabras y el OP realmente significa filtrar filas? No estoy seguro ... –

0

en general, añadir una WHERE cláusula para su consulta, por ejemplo

WHERE a IS NOT NULL AND b IS NOT NULL AND c IS NOT NULL 

Aquí, a b c son sus nombres de columna.

Si está uniendo tablas en columnas potencialmente NULL, utilice INNER JOIN y los valores NULL no se incluirán.

EDITAR: Puede que no haya entendido bien: lo anterior filtra las filas, pero es posible que solicite que se filtren las columnas, p. tiene varias columnas y solo desea mostrar columnas que contengan al menos un valor nulo en todas las filas que está devolviendo. El uso de SQL dinámico ofrece una solución, ya que las columnas configuradas varían según sus datos.

Aquí hay una consulta SQL que crea otra consulta SQL que contiene las columnas adecuadas. Puede ejecutar esta consulta y luego enviar su resultado como otra consulta. Supone que 'pk' es alguna columna que siempre es no nula, p. una clave principal: esto significa que podemos prefijar nombres de filas adicionales con una coma.

SELECT CONCAT("SELECT pk" 
    CASE (count(columnA)) WHEN 0 THEN '' ELSE ',columnA' END, 
    CASE (count(columnB)) WHEN 0 THEN '' ELSE ',columnB' END, 
    // etc.. 
    ' FROM (YourQuery) base') 
FROM 
    (YourQuery) As base 

La consulta funciona usando Count (columna) - la función de agregado ignora valores NULL, y así devuelve 0 para una columna que consiste en su totalidad de valores nulos. El generador de consultas asume que YourQuery utiliza alias para garantizar que no haya nombres de columna duplicados.

Si bien no puede poner esto en una vista, podría resumirlo como un procedimiento almacenado que copia los datos en otra tabla: la tabla de resultados. También puede configurar un disparador para que la tabla de resultados se actualice cada vez que cambien las tablas base.

3

No hay forma de hacerlo en sql.

+1

Estuve tentado de responder de esta manera, pero depende del sistema de la base de datos. Desde entonces pensé que podría ser posible con una tabla temporal, pero la lógica sería bastante intrincada. Es posible hacerlo con SQL generado dinámicamente, pero ese método tiene aún más salvedades. – eksortso

+2

No se puede utilizar ninguna de esas técnicas en una vista. –

+2

110% correcto. SQL = salida de columna fija. – gbn

0

Si leemos bien su pregunta, no habrá forma de hacerlo en SQL. La salida de una vista debe ser una relación - en términos (excesivamente) simplificados, debe ser rectangular. Es decir, cada fila debe tener el mismo número de columnas.

Si nos puede decir más acerca de sus datos y darnos una idea de lo que quiere hacer con la salida, quizás podamos ofrecer más sugerencias positivas.

0

No se puede hacer esto en una vista, pero puede hacerlo bastante fácilmente usando SQL dinámico en un procedimiento almacenado.

Por supuesto, tener un esquema que cambia no es necesariamente bueno para los clientes que consumen los datos, pero puede ser eficiente si tiene datos muy dispersos Y el cliente consumidor entiende el esquema variable.

Si tiene que tener una vista, puede poner una fila de "encabezado" en su vista que puede inspeccionar del lado del cliente en la primera fila de su ciclo para ver si no quiere molestarse con la columna en su rejilla o lo que sea, se puede hacer algo como esto:

SELECT * FROM (
    -- This is the view code 
    SELECT 'data' as typ 
      ,int_col 
      ,varchar_col 
    FROM TABLE 

    UNION ALL 

    SELECT 'hdr' as typ 
      -- note that different types have to be handled differently 
      ,CASE WHEN COUNT(int_col) = 0 THEN NULL ELSE 0 END 
      ,CASE WHEN COUNT(varchar_col) = 0 THEN NULL ELSE '' END 
    FROM TABLE 
) AS X 
-- have to get header row first 
ORDER BY typ DESC -- add other sort criteria here 
0

sospecho que lo que está pasando es que un usuario final se está ejecutando CrystalReports y quejándose de todas las columnas vacías que tienen que ser eliminado de forma manual.

En realidad, sería posible crear un procedimiento almacenado que cree una vista sobre la marcha, omitiendo las columnas sin datos. Pero entonces tendrías que ejecutar este proceso antes de usar la vista.

¿Eso es aceptable?

Cuestiones relacionadas