Comment extrapoler les dates en SQL Server pour calculer le décompte de la journée?

0

La question

C'est de cette façon l'apparence des données. C'est une longue table

enter image description here

J'ai besoin de calculer le nombre de personnes employées par jour

enter image description here

Comment écrire de SQL Server logique pour obtenir ce résultat? Je treid pour créer une des DATES de la table, puis de la rejoindre, mais cela a provoqué une erreur parce que le tableau est trop grand. Ai-je besoin d'une logique récursive?

sql sql-server tsql
2021-11-23 19:56:48
4
0

Pour les questions d'avenir, ne postez pas d'images de données. Au lieu de cela, utiliser un service comme dbfiddle. Je vais de toute façon ajouter une esquisse pour une réponse, mieux préparés question que vous auriez obtenu une réponse complète. De toute façon ici il va:

-- extrema is the least and the greatest date in staff table
with extrema(mn, mx) as (
    select least(min(hired),min(retired)) as mn
         , greatest(max(hired),max(retired)) as mx
    from staff
), calendar (dt) as (
    -- we construct a calendar with every date between extreme values
    select mn from extrema
    union all
    select dateadd(day, 1, d)
    from calendar
    where dt < (select mx from extrema)
)
-- finally we can count the number of employed people for each such date
select dt, count(1) 
from calendar c 
join staff s
    on c.dt between s.hired and s.retired
group by dt; 

Si vous vous retrouver à faire ce genre de calcul, il est souvent une bonne idée de créer un calendrier de table. Vous pouvez ajouter d'autres attributs tels que si c'est un jour de dans le milieu de la semaine, etc.

Avec une contrainte:

CHECK(hired <= retired)

la première partie peut être simplifiée comme suit:

with extrema(mn, mx) as (
    select min(hired) as mn
         , max(retired) as mx
    from staff
),
2021-11-23 20:45:14
0

En supposant que les Employés Actuels ont une valeur NULLE de la date de retraite

Declare @Date1 date = '2015-01-01'
Declare @Date2 date = getdate()

Select A.Date
      ,HeadCount = count(B.name)
 From ( Select Top (DateDiff(DAY,@Date1,@Date2)+1) 
               Date=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),@Date1) 
         From  master..spt_values n1,master..spt_values n2
      ) A
 Left Join YourTable B on A.Date >= B.Hired and A.Date <= coalesce(B.Retired,getdate())
 Group BY A.Date
2021-11-23 20:34:49
0

Vous avez besoin d'un calendrier de table pour cela. Vous commencez avec le calendrier, et à GAUCHE, REJOINDRE tout le reste, à l'aide de BETWEEN la logique.

Vous pouvez utiliser une table réelle. Ou vous pouvez la générer à la volée, comme ceci:

WITH
    L0 AS ( SELECT c = 1
            FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),
                        (1),(1),(1),(1),(1),(1),(1),(1)) AS D(c) ),
    L1 AS ( SELECT c = 1 FROM L0 A, L0 B, L0 C, L0 D ),
    Nums AS ( SELECT rownum = ROW_NUMBER() OVER(ORDER BY (SELECT 1))
              FROM L1 ),
    Dates AS (
      SELECT TOP (DATEDIFF(day, '20141231', GETDATE()))
        Date = DATEADD(day, rownum, '20141231')
      FROM Nums
    )

SELECT
  d.Date,
  NumEmployed = COUNT(*)
FROM Dates d
JOIN YourTable t ON d.Date BETWEEN t.Hired AND t.Retired
GROUP BY
  d.Date;

Si vos dates ont une composante temporelle, alors vous devez utiliser >= AND < la logique

2021-11-23 20:49:37
0

Essayez de limiter le champ d'application de la date de votre table. Dans cet exemple j'ai une table de dates nommé TallyStickDT.

SELECT dt, COUNT(name)
FROM (
    SELECT dt
    FROM tallystickdt
    WHERE dt >= (SELECT MIN(hired) FROM #employees)
    AND dt <= GETDATE()
) A
LEFT OUTER JOIN #employees E ON A.dt >= E.Hired AND A.dt <= e.retired
GROUP BY dt
ORDER BY dt
2021-11-23 20:44:03

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................