Come estrapolare le date in SQL Server per calcolare la quotidiana conta?

0

Domanda

Questo è il modo in cui i dati assomiglia. Si tratta di un lungo tavolo

enter image description here

Ho bisogno di calcolare il numero di persone impiegate da giorno

enter image description here

Come scrivere la logica di SQL Server per ottenere questo risultato? Ho treid per creare un DATE tabella e quindi unire, ma questo ha causato un errore perché il tavolo è troppo grande. Ho bisogno di una logica ricorsiva?

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

Per domande future, non postare immagini di dati. Invece, utilizzare un servizio come dbfiddle. Io comunque aggiungere uno schizzo per una risposta, con un meglio preparato domanda si potrebbe avere ottenuto una risposta completa. Comunque qui si 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; 

Se ti trovi a fare questo tipo di calcolo, spesso, è una buona idea per creare una tabella di calendario. È possibile aggiungere altri attributi come se è un giorno in mezzo alla settimana, etc.

Con un vincolo, come:

CHECK(hired <= retired)

la prima parte può essere semplificata:

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

Supponendo che i Dipendenti Attuali hanno un valore NULL data di pensionamento

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

Hai bisogno di una tabella di calendario per questo. Si inizia con il calendario, e LEFT JOIN tutto il resto, utilizzando BETWEEN di logica.

È possibile utilizzare una tabella reale. Oppure è possibile generare al volo, come questo:

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;

Se le date sono una componente di tempo, allora avete bisogno di utilizzare >= AND < la logica

2021-11-23 20:49:37
0

Provare a limitare l'ambito della tabella data. In questo esempio ho una tabella di date nome 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

In altre lingue

Questa pagina è in altre lingue

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