簡體   English   中英

獲得員工的出生日期為-30天

[英]Get Birthdates of employees for a period of +-30 days

我是SQL的新手。 對於我的SAP附加組件,我需要一個SQL查詢來顯示員工的出生日期為+ -30天(這將是最后給出int的用戶)。 我根據自己的理解寫了一個查詢,它只限制了當月的周期。 例如:如果當前日期是2016.01.15,則正確的查詢應顯示12月16日至2月14日期間的出生日期。 但我只看到1月份的出生日期。你可以看到下面的查詢。

SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1], 
T0.[E_MailL] FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode 
WHERE DATEADD( Year, DATEPART( Year, GETDATE()) - DATEPART( Year, T0.[BirthDate]), 
T0.[BirthDate]) BETWEEN CONVERT( DATE, GETDATE()-30)AND CONVERT( DATE, GETDATE() +30); 

為了獲得正確的結果,我應該做些什么改變? 任何幫助將非常感謝! :-)

這樣的事情怎么樣:

SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1], T0.[E_MailL] 
FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode 
WHERE TO.[BirthDate] BETWEEN DATEADD(DAY, -30, GETDATE()) AND DATEADD(DAY, +30, GETDATE()) 

您可以在評論中調整我引用答案 ,如下所示:

SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1], T0.[E_MailL]
FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode
WHERE 1 = (FLOOR(DATEDIFF(dd,TO.Birthdate,GETDATE()+30) / 365.25))
          -
          (FLOOR(DATEDIFF(dd,TO.Birthdate,GETDATE()-30) / 365.25))

根據Vladimir的評論,如果需要,您可以將' 365.25 '修改為' 365.2425 '以獲得更好的准確性。

我在SQL Server中測試它,因為它具有DATEADDGETDATE函數。

當-30天的范圍跨越1月1日時,即范圍屬於兩年時,您的查詢會返回錯誤的結果。

你的計算

DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART( Year, T0.[BirthDate]), T0.[BirthDate])

BirthDate的年份移至與GETDATE相同的年份,因此如果GETDATE返回2016-01-01 ,那么BirthDate=1957-12-25將變為2016-12-25 但是您的范圍是從2015-12-012016-01-30並且調整后的BirthDate不屬於它。

有許多方法可以將這一年度的邊界考慮在內。

一種可能的變體是從2015-12-012016-01-30不是一個范圍,而是三個 - 在下一年和前幾年也是如此:

from `2014-12-01` to `2015-01-30`
from `2015-12-01` to `2016-01-30`
from `2016-12-01` to `2017-01-30`

還有一點需要注意 - 最好將原始BirthDate與某些計算結果進行比較,而不是轉換BirthDate並比較函數的結果。 在第一種情況下,優化器可以在BirthDate上使用索引,在第二種情況下它不能。

這是我在SQL Server 2008中測試的完整示例。

DECLARE @T TABLE (BirthDate date);

INSERT INTO @T (BirthDate) VALUES
('2016-12-25'),
('2016-01-25'),
('2016-02-25'),
('2016-11-25'),
('2015-12-25'),
('2015-01-25'),
('2015-02-25'),
('2015-11-25'),
('2014-12-25'),
('2014-01-25'),
('2014-02-25'),
('2014-11-25');

--DECLARE @CurrDate date = '2016-01-01';
DECLARE @CurrDate date = '2015-12-31';
DECLARE @VarDays int = 30;

我使用變量@CurrDate而不是GETDATE來檢查它在不同情況下的工作原理。

DATEDIFF(year, @CurrDate, BirthDate)@CurrDateBirthDate之間@CurrDate的差異

DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate) @CurrDateBirthDate同年搬遷

最后的DATEADD(day, -@VarDays, ...)DATEADD(day, +@VarDays, ...)的范圍為+-@VarDays

對於“主要”以及前一年和下一年,此范圍創建三次。

SELECT
    BirthDate
FROM @T
WHERE
    (
        BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
        AND
        BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
    )
    OR
    (
        BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
        AND
        BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
    )
    OR
    (
        BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
        AND
        BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
    )
;

結果

+------------+
| BirthDate  |
+------------+
| 2016-12-25 |
| 2016-01-25 |
| 2015-12-25 |
| 2015-01-25 |
| 2014-12-25 |
| 2014-01-25 |
+------------+

我已經簡化了一點。 我已經注釋了進行計算的代碼,所以回顧未來你會知道它在做什么(通常是一個救世主):)。

SELECT T0.[BirthDate], 
       T0.[CardCode], 
       T1.[CardName], 
       T0.[Name], 
       T0.[Tel1], 
       T0.[E_MailL]
FROM OCPR T0 
INNER JOIN OCRD T1 
ON T0.CardCode = T1.CardCode 
WHERE T0.[BirthDate] >= GETDATE()       -- Where the birthday is greater than or equal to today's date
AND   T0.[BirthDate] <= GETDATE() + 30  -- Where the birthday is less than or equal to today's date plus 30 days.

您可以嘗試使用DAYOFYEAR:

SELECT T0.[BirthDate], 
       T0.[CardCode], 
       T1.[CardName], 
       T0.[Name], 
       T0.[Tel1], 
       T0.[E_MailL]
FROM OCPR T0 
INNER JOIN OCRD T1 
ON T0.CardCode = T1.CardCode
WHERE IF(DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE()) < 0, DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE()) + DayOfYear(DATE_FORMAT(CURDATE(),"%Y-12-31")), DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE())) <= 30
OR IF(DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate]) < 0, DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate]) + DayOfYear(DATE_FORMAT(CURDATE(),"%Y-12-31")), DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate])) <= 30

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM