Günlük sayımları hesaplamak için SQL Server'da tarihleri nasıl tahmin edebilirim?

0

Soru

Veriler böyle görünüyor. Uzun bir masa var

enter image description here

Günlük çalışan sayısını hesaplamam gerekiyor.

enter image description here

Bu sonucu elde etmek için SQL Server mantığı nasıl yazılır? Bir TARİH tablosu oluşturmak ve sonra katılmak istiyorum, ancak tablo çok büyük olduğu için bu bir hataya neden oldu. Özyinelemeli mantığa ihtiyacım var mı?

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

Gelecekteki sorularınız için verilerin resimlerini göndermeyin. Bunun yerine, dbfiddle gibi bir hizmet kullanın. Her neyse, bir cevap için bir taslak ekleyeceğim, daha iyi hazırlanmış bir soruyla tam bir cevap almış olabilirsiniz. Her neyse işte gidiyor:

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

Kendinizi sık sık bu tür bir hesaplama yaparken bulursanız, bir takvim tablosu oluşturmak iyi bir fikirdir. Haftanın ortasında bir gün gibi başka nitelikler de ekleyebilirsiniz.

Bir kısıtlama ile:

CHECK(hired <= retired)

ilk bölüm basitleştirilebilir:

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

Mevcut Çalışanların BOŞ bir emeklilik tarihi olduğunu varsayarsak

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

Sana ihtiyaçları takvimi tablo bu. Takvimle başlıyorsunuz ve kalan her şeye katılıyorsunuz BETWEEN mantık.

Gerçek bir masa kullanabilirsin. Ya da bu şekilde anında üretebilirsiniz:

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;

Tarihlerinizin bir saat bileşeni varsa, kullanmanız gerekir >= AND < mantık

2021-11-23 20:49:37
0

Tarih tablonuzun kapsamını sınırlamayı deneyin. Bu örnekte TallyStickDT adlı bir tarih tablosu var.

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

Diğer dillerde

Bu sayfa diğer dillerde

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