Cum de a extrapola datele din SQL Server pentru a calcula zilnic contează?

0

Problema

Acesta este modul în care datele arata ca. E o masă lungă

enter image description here

Am nevoie pentru a calcula numărul de persoane angajate de zi

enter image description here

Cum să scrie SQL Server logica pentru a obține acest rezultat? Am căutat să creeze o DATELE de masă și apoi se alăture, dar acest lucru a cauzat o eroare, deoarece masa este prea mare. Am nevoie de un recursiv logica?

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

Pentru întrebări viitor, nu posta imagini de date. În schimb, utilizați un serviciu ca dbfiddle. Voi oricum adăugați o schiță pentru un răspuns, cu atât mai bine-pregătit întrebare ai fi putut obține un răspuns complet. Oricum aici merge:

-- 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; 

Dacă faci acest tip de calcul, de multe ori, este o idee bună pentru a crea un calendar de masă. Puteți adăuga alte atribute, cum ar fi dacă este o zi de la mijlocul săptămânii etc.

Cu o constrângere ca:

CHECK(hired <= retired)

prima parte poate fi simplificată la:

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

Presupunând că Angajații actuali ai un NULL data de pensionare

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

Ai nevoie de un calendar de masă pentru acest lucru. Începe cu calendar, și a LĂSAT totul altceva, folosind BETWEEN logica.

Puteți utiliza un tabel real. Sau puteti genera pe zbor, astfel:

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;

Dacă datele au o componentă de timp, atunci ai nevoie pentru a utiliza >= AND < logica

2021-11-23 20:49:37
0

Încercați să limiteze domeniul de aplicare de data masă. În acest exemplu am un tabel cu date pe nume 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

În alte limbi

Această pagină este în alte limbi

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