Как экстраполировать даты в SQL Server для расчета количества дней?

0

Вопрос

Вот как выглядят данные. Это длинный стол

enter image description here

Мне нужно подсчитать количество занятых за день

enter image description here

Как написать логику SQL Server, чтобы получить этот результат? Я попытался создать таблицу ДАТ, а затем присоединиться, но это вызвало ошибку, потому что таблица слишком большая. Нужна ли мне рекурсивная логика?

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

Для будущих вопросов не публикуйте изображения данных. Вместо этого используйте такую службу, как dbfiddle. В любом случае я добавлю набросок ответа с более подготовленным вопросом, на который вы могли бы получить полный ответ. В любом случае, вот оно:

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

Если вы часто выполняете такого рода вычисления, рекомендуется создать таблицу календаря. Вы можете добавить к нему другие атрибуты, например, если это день в середине недели и т. Д.

С ограничением в виде:

CHECK(hired <= retired)

первую часть можно упростить до:

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

Предполагая, что у нынешних сотрудников НУЛЕВАЯ дата выхода на пенсию

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

Для этого вам нужна таблица календаря. Вы начинаете с календаря, а ЗАТЕМ ПРИСОЕДИНЯЕТЕСЬ ко всему остальному, используя BETWEEN Логические.

Вы можете использовать настоящую таблицу. Или вы можете сгенерировать его на лету, вот так:

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;

Если в ваших датах есть компонент времени, вам необходимо использовать >= AND < Логические

2021-11-23 20:49:37
0

Попробуйте ограничить область действия вашей таблицы дат. В этом примере у меня есть таблица дат с именем 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

На других языках

Эта страница на других языках

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

Популярное в этой категории

Популярные вопросы в этой категории