0
votes

Obtenez le nombre de dates non nulles à partir de la même ligne

On dirait que ça devrait être facile. Comment obtenir le nombre de cellules où les dates ne sont pas nulles dans différentes colonnes.

call_case    NOT NULL
Key1            2 
Key2            1 
Key3            3
Key4            2 

Je voudrais que le résultat soit:

DROP TABLE #indebtedness
CREATE TABLE #indebtedness (call_case CHAR(10), date1 DATETIME, date2 DATETIME, date3 DATETIME)
INSERT #indebtedness VALUES ('Key1', '2019-10-30', '2019-11-30',      null   )
INSERT #indebtedness VALUES ('Key2',   NULL      ,     null    , '2019-10-15')
INSERT #indebtedness VALUES ('Key3', '2019-11-11', '2019-10-29', '2019-10-30')
INSERT #indebtedness VALUES ('Key4',     null    , '2019-10-29', '2019-10-13')


0 commentaires

4 Réponses :


2
votes

Cela devrait le faire:

SELECT 
  call_case, 
  CASE WHEN date1 IS NOT NULL THEN 1 ELSE 0 END + 
    CASE WHEN date2 IS NOT NULL THEN 1 ELSE 0 END + 
    CASE WHEN date3 IS NOT NULL THEN 1 ELSE 0 END 
  AS "NOT NULL"
FROM indebtedness
;


0 commentaires

1
votes

Vous pouvez aligner les trois colonnes en utilisant une union, puis utiliser la fonction COUNT :

WITH cte AS (
    SELECT call_case, date1 AS date FROM #indebtedness UNION ALL
    SELECT call_case, date2 FROM #indebtedness UNION ALL
    SELECT call_case, date3 FROM #indebtedness
)

SELECT
    call_case,
    COUNT(date) AS [NOT NULL]
FROM cte
GROUP BY
    call_case;

En fait, si vous avez des besoins à long terme pour les requêtes similaire à celui-ci, cela peut impliquer que votre modèle de données devrait changer et que vous ne devriez avoir qu'une seule colonne de date.


0 commentaires

0
votes

c'est assez délicat en raison des valeurs null , j'ai utilisé sql server min date 17530101 sur la base de celles-ci valeurs nulles.

select call_case, iif(isnull(date1,0)=0, 0, 1) 
    + iif(isnull(date2,0)=0, 0, 1) 
    + iif(isnull(date3,0)=0, 0, 1)  from
#indebtedness 

ou

select call_case, iif(coalesce(date1, '17530101')='17530101', 0, 1) 
    + iif(coalesce(date2, '17530101')='17530101', 0, 1) 
    + iif(coalesce(date3, '17530101')='17530101', 0, 1) from
#indebtedness 


0 commentaires

2
votes

Si les colonnes sont nombreuses et que vous ne voulez pas les coder en dur ou créer une logique complexe - par exemple vérifier les colonnes avec un type ou un nom particulier, vous pouvez utiliser les vues système pour créer une telle expression dynamique.

Dans votre cas:

DROP TABLE dbo.indebtedness
CREATE TABLE dbo.indebtedness (call_case CHAR(10), date1 DATETIME, date2 DATETIME, date3 DATETIME)
INSERT dbo.indebtedness VALUES ('Key1', '2019-10-30', '2019-11-30',      null   )
INSERT dbo.indebtedness VALUES ('Key2',   NULL      ,     null    , '2019-10-15')
INSERT dbo.indebtedness VALUES ('Key3', '2019-11-11', '2019-10-29', '2019-10-30')
INSERT dbo.indebtedness VALUES ('Key4',     null    , '2019-10-29', '2019-10-13')


DECLARE @DynammicTSQLStatement NVARCHAR(MAX)
       ,@DynamicColumns NVARCHAR(MAX);

SET @DynamicColumns = STUFF
                          (
                                (
                                    SELECT ' + CASE WHEN ' + QUOTENAME(C.[name]) + 'IS NULL THEN 0 ELSE 1 END'
                                    FROM [sys].[columns] C
                                    INNER JOIN [sys].[types] T
                                        ON C.[system_type_id] = T.[system_type_id]
                                    WHERE [object_id] = OBJECT_ID('dbo.indebtedness')
                                        AND T.[name] = 'datetime'
                                    ORDER BY C.[name]
                                    FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,3
                                ,''
                          );

SET @DynammicTSQLStatement = 'SELECT call_case, ' + @DynamicColumns + ' AS [NOT NULL] FROM dbo.indebtedness;'

EXEC sp_executesql @DynammicTSQLStatement;


0 commentaires