Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Selecione colunas não vazias usando o SQL Server


Não sei se isso é mais rápido, mas você pode usar um truque:FOR XML AUTO irá omitir colunas sem conteúdo:
DECLARE @tbl TABLE(col1 INT,col2 INT,col3 INT);
INSERT INTO @tbl VALUES (1,2,NULL),(1,NULL,NULL),(NULL,NULL,NULL);

SELECT * 
FROM @tbl AS tbl
FOR XML AUTO

Este é o resultado:col3 está desaparecido...
<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />

Sabendo disso, você pode encontrar a lista de colunas, que não são NULL em todas as linhas, assim:
DECLARE @ColList VARCHAR(MAX)=
STUFF
(
    (
    SELECT DISTINCT ',' + Attr.value('local-name(.)','nvarchar(max)')
    FROM
    (
        SELECT
        (
            SELECT *
            FROM @tbl AS tbl
            FOR XML AUTO,TYPE
        ) AS TheXML
    ) AS t
    CROSS APPLY t.TheXML.nodes('/tbl/@*') AS A(Attr) 
    FOR XML PATH('')
    ),1,1,''
);

SELECT @ColList

O conteúdo de @ColList agora é col1,col2 . Esta string você pode colocar em um SELECT criado dinamicamente .

ATUALIZAÇÃO:Dicas


Seria muito inteligente, substituir o SELECT * com uma lista de colunas criada a partir de INFORMATION_SCHEMA.COLUMNS excluindo todos os não anuláveis . E - se necessário e possível - tipos, que contêm dados muito grandes (BLOBs).

ATUALIZAÇÃO2:Desempenho


Não sei quais são seus dados muito grandes significa na verdade... Tentei isso em uma tabela com cerca de 500.000 linhas (com SELECT * ) e retornou corretamente após menos de um minuto. Espero que seja rápido o suficiente...