sql >> Database >  >> RDS >> Sqlserver

Selecteer niet-lege kolommen met SQL Server

Ik weet niet of dit sneller is, maar je zou een truc kunnen gebruiken:FOR XML AUTO zal kolommen zonder inhoud weglaten:

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

Dit is het resultaat:col3 ontbreekt...

<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />

Als u dit weet, kunt u de lijst met kolommen, die niet in alle rijen NULL zijn, als volgt vinden:

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

De inhoud van @ColList is nu col1,col2 . Deze string kun je plaatsen in een dynamisch aangemaakte SELECT .

UPDATE:tips

Het zou heel slim zijn om de SELECT * . te vervangen met een kolomlijst gemaakt op basis van INFORMATION_SCHEMA.COLUMNS exclusief alle niet-nullable . En - indien nodig en mogelijk - typen, die zeer grote gegevens (BLOB's) bevatten.

UPDATE2:Prestaties

Weet niet wat uw zeer grote gegevens betekent eigenlijk... Ik heb dit net geprobeerd op een tafel met ongeveer 500.000 rijen (met SELECT * ) en het keerde correct terug na minder dan een minuut. Hoop, dit is snel genoeg...



  1. Een onderliggende node invoegen in een XMLTYPE-kolom

  2. Waarden doorgeven aan MySQL IN-bewerking in door PDO voorbereide instructie?

  3. Nde max salaris in Oracle

  4. Android:hoe een contact van de telefoon importeren?