0
votes

Comment obtenir DateTime ne peut pas insérer à la table?

J'ai des données comme celle-ci.

select Userid
     ,sum(case when CheckIn < '08:00' then 1 else 0 end) as TotalLate
     ,'?' as TotalDateOff 
from WorkingTime 
where RegDay between '2019-04-03' and '2019-04-11'
group by Userid


6 commentaires

Microsoft SQL Server ou Postgres? Ce sont deux produits DBMS très différents


J'ai 1 projet mais publier pour 2 dB: Microsoft SQL Server et Postgres. Je pense que cela peut être la même solution


Votre dernière ligne qui est votre exigence n'est pas claire. Pouvez-vous s'il vous plaît expliquer un peu plus?


Vous pouvez voir du '2019-04-03' à '2019-04-11', nous avons 4 jours de congé. Mais comment ça peut le calculer?


Est un checkin avant 08:00 vraiment considéré comme "en retard". Cette condition ne devrait-elle pas être checkin> '08: 00 '?


compter () fonctionnera


3 Réponses :


0
votes

Pour ajouter des données, vous avez besoin d'une source de données. Dans ce cas, vous avez besoin d'une source qui a toutes les dates possibles. Ceci est un problème courant qui prend plusieurs formes - dans votre cas, vous devez créer une table pour toutes les dates, puis vous essayez de trouver ce qui existe et non ici. Par exemple, une table de calendrier.

D'autres utilisations pour une telle table consiste à définir l'exercice financier, quartier fiscal, peut-être des vacances, etc.

Vous pouvez également créer une telle [source] via une fonction que vous pouvez appeler de la clause - mais la meilleure et la plus simple option est probablement d'avoir une table. Vous pouvez le générer pendant 1000 ans et être fait!


0 commentaires

1
votes

Une méthode consiste à utiliser CTE pour obtenir une liste de dates (de - à), qui sera incrémentielle au jour ou au mois ou quelle que soit la méthode supplémentaire requise.

Vous pouvez l'utiliser dans votre CTE actuel en l'ajoutant à l'actuel qui obtiendra la date minimale et l'incrément d'une journée jusqu'à ce qu'il atteigne la date maximale. Ensuite, tout ce dont vous avez besoin est une simple jointure gauche, qui rejoindra les dates, si la date n'est pas existante dans le temps de travail, ce sera une valeur nulle. Ensuite, tout ce que vous avez besoin pour compter ces NULLS pour obtenir la date totale. P>

Exemple: P>

;with WorkingTime as(
    select 1 Userid, '2019-04-03' RegDay, '08:48' CheckIn, '18:00' CheckOut union all
    select 1 , '2019-04-05' , '08:00' , '18:00'  union all
    select 1 , '2019-04-06' , '07:48' , '18:00'  union all
    select 1 , '2019-04-09' , '08:20' , '18:00'  
) , WorkingOff AS (
    SELECT Userid, CAST(MIN(RegDay) AS DATE) MinRegDay
    FROM WorkingTime
    GROUP BY Userid
    UNION ALL 
    SELECT Userid,  DATEADD(DAY, 1, MinRegDay)
    FROM WorkingOff
    WHERE 
        DATEADD(DAY, 1, MinRegDay) < '2019-04-11'
) 
SELECT 
    wf.Userid
,   SUM(CASE WHEN wt.CheckIn < '08:00' THEN 1 ELSE 0 END) TotalLate
,   SUM(CASE WHEN wt.RegDay IS NULL THEN 1 ELSE 0 END) TotalDateOff 
FROM WorkingOff wf
LEFT JOIN WorkingTime wt ON wf.MinRegDay = wt.RegDay AND wf.Userid = wt.Userid
where wf.MinRegDay between '2019-04-03' and '2019-04-11'
GROUP BY wf.Userid


0 commentaires

1
votes

Pour postgres, cela peut être effectué à l'aide de générate_series () pour générer la liste des dates pour chaque utilisateur et l'utilisation que dans une jointure gauche: xxx

le Vers les retours ci-dessus: xxx


0 commentaires