Jak ekstrapolować datę w SQL Server do obliczania liczby dni?

0

Pytanie

Oto jak wyglądają dane. To długi stół

enter image description here

Muszę policzyć liczbę zatrudnionych za dzień

enter image description here

Jak napisać logiki programu SQL Server, aby uzyskać ten wynik? Próbowałem utworzyć tabelę DAT, a następnie dołączyć, ale to spowodowało błąd, bo tabela jest zbyt duża. Czy potrzebuję rekurencyjnie logika?

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

Dla przyszłych pytań nie wolno publikować danych obrazu. Zamiast tego należy użyć taką usługę, jak dbfiddle. W każdym razie ja dodam szkic odpowiedzi z bardziej przygotowanym pytaniem, na które można uzyskać pełną odpowiedź. W każdym razie, oto ono:

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

Jeśli często wykonujesz tego rodzaju obliczeń, należy utworzyć tabelę kalendarza. Można dodać do niego inne atrybuty, na przykład, jeśli jest to dzień, w środku tygodnia, itp.

Z ograniczeniem w postaci:

CHECK(hired <= retired)

pierwszą część można uprościć do:

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

Zakładając, że u obecnych pracowników ZEROWA data przejścia na emeryturę

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

Do tego potrzebujesz tabela kalendarza. Zaczynasz z kalendarza, a NASTĘPNIE PRZYŁĄCZYĆ się do reszty, za pomocą BETWEEN Logiczne.

Możesz użyć niniejszej tabeli. Lub możesz wygenerować go w locie, tak:

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;

Jeśli w waszych dat jest składnik czasu, należy użyć >= AND < Logiczne

2021-11-23 20:49:37
0

Spróbuj ograniczyć zakres swojej tabeli dat. W tym przykładzie mam tabela dat z nazwą 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

W innych językach

Ta strona jest w innych językach

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