28

誕生日が近づいている従業員を選択するためのストアド プロシージャを作成しようとしています。

SELECT * FROM Employees WHERE Birthday > @Today AND Birthday < @Today + @NumDays

誕生年は誕生日の一部であるため、これは機能しません。つまり、私の誕生日が '09-18-1983' の場合、'09-18-2008' と '09-25-2008' の間には入りません。

日付フィールドの年の部分を無視して、月/日だけを比較する方法はありますか?

これは毎週月曜日の朝に実行され、マネージャーに誕生日が近づいていることを警告するため、新しい年にまたがる可能性があります。

これが、私が最終的に作成した実用的なソリューションです。Kogus に感謝します。

SELECT * FROM Employees 
WHERE Cast(DATEDIFF(dd, birthdt, getDate()) / 365.25 as int)
    - Cast(DATEDIFF(dd, birthdt, futureDate) / 365.25 as int) 
<> 0
4

36 に答える 36

39

注: これを編集して、重大なバグであると思われるものを修正しました。現在投稿されているバージョンは私にとってはうまくいきます。

これは、データベースに対応するようにフィールドとテーブルの名前を変更した後に機能するはずです。

SELECT 
  BRTHDATE AS BIRTHDAY
 ,FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()) / 365.25) AS AGE_NOW
 ,FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()+7) / 365.25) AS AGE_ONE_WEEK_FROM_NOW
FROM 
  "Database name".dbo.EMPLOYEES EMP
WHERE 1 = (FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()+7) / 365.25))
          -
          (FLOOR(DATEDIFF(dd,EMP.BRTHDATE,GETDATE()) / 365.25))

基本的に、誕生日から現在までの日数を取得し、それを 365 で割ります (年に直接変換するときに発生する四捨五入の問題を回避するため)。

次に、誕生日から 1 週間後までの日数を取得し、それを 365 で割り、今から 1 週間後の年齢を取得します。

誕生日が 1 週間以内の場合、これら 2 つの値の差は 1 になります。したがって、これらのレコードがすべて返されます。

于 2008-09-17T14:25:07.297 に答える
17

誰かがまだMySQLで解決策を探している場合(わずかに異なるコマンド)、クエリは次のとおりです。

SELECT
 name,birthday,
 FLOOR(DATEDIFF(DATE(NOW()),birthday) / 365.25) AS age_now,
 FLOOR(DATEDIFF(DATE_ADD(DATE(NOW()),INTERVAL 30 DAY),birthday) / 365.25) AS age_future

FROM user

WHERE 1 = (FLOOR(DATEDIFF(DATE_ADD(DATE(NOW()),INTERVAL 30 DAY),birthday) / 365.25)) - (FLOOR(DATEDIFF(DATE(NOW()),birthday) / 365.25))

ORDER BY MONTH(birthday),DAY(birthday)
于 2011-04-20T15:27:51.977 に答える
11

datediff と dateadd の最適な使用。丸めなし、概算なし、2 月 29 日バグなし、日付関数のみ

  1. ageOfThePerson = DATEDIFF(yyyy,dateOfBirth, GETDATE())

  2. dateOfNextBirthday = DATEADD(yyyy,ageOfThePerson + 1, dateOfBirth)

  3. daysBeforeBirthday = DATEDIFF(d,GETDATE(), dateofNextBirthday)

@Gustavo Cardoso のおかげで、人の年齢の新しい定義

  1. ageOfThePerson = FLOOR(DATEDIFF(d,dateOfBirth, GETDATE())/365.25)
于 2008-09-17T15:12:50.817 に答える
3

@strelc のアプローチは気に入りましたが、彼の sql は少しずれていました。これは、うまく機能し、使いやすい更新バージョンです。

SELECT * FROM User 
WHERE (DATEDIFF(dd, getdate(), DATEADD(yyyy, 
    DATEDIFF(yyyy, birthdate, getdate()) + 1, birthdate)) + 1) % 366 <= <number of days>

編集 10/2017: 1 日を最後に追加

于 2012-05-25T21:12:02.510 に答える
2

この関数を使用することもできますがDAYOFYEAR、12月の1月の誕生日を検索する場合は注意が必要です。お探しの日付範囲が正月を超えない限り、大丈夫だと思います。

于 2008-09-17T14:05:14.537 に答える
2

申し訳ありませんが、年を無力化するための要件を見ていませんでした。

select * from Employees
where DATEADD (year, DatePart(year, getdate()) - DatePart(year, Birthday), Birthday)
      between convert(datetime, getdate(), 101) 
              and convert(datetime, DateAdd(day, 5, getdate()), 101)

これは機能するはずです。

于 2008-09-17T14:14:40.787 に答える
1

これはMSSQLServerのソリューションです。30日以内に誕生日のある従業員を返します。

SELECT * FROM rojstni_dnevi
  WHERE (DATEDIFF   (dd, 
                    getdate(), 
                    DATEADD (   yyyy, 
                                DATEDIFF(yyyy, rDan, getdate()),
                                rDan)
    nex             )
        +365) % 365 < 30
于 2010-11-10T09:12:55.340 に答える
1

私はこれに対する解決策を見つけました。これは誰かの貴重な時間を節約するかもしれません。

 select EmployeeID,DOB,dates.date  from emp_tb_eob_employeepersonal 
 cross join dbo.GetDays(Getdate(),Getdate()+7) as dates where weekofmonthnumber>0
 and month(dates.date)=month(DOB) and day(dates.date)=day(DOB)



GO
/****** Object:  UserDefinedFunction [dbo].[GetDays]    Script Date: 11/30/2011 13:19:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--SELECT [dbo].[GetDays] ('02/01/2011','02/28/2011')

ALTER FUNCTION [dbo].[GetDays](@startDate datetime, @endDate datetime)
RETURNS @retValue TABLE
(Days int ,Date datetime, WeekOfMonthNumber int, WeekOfMonthDescription varchar(10), DayName varchar(10))
AS
BEGIN
    DECLARE @nextDay int
    DECLARE @nextDate datetime 
    DECLARE @WeekOfMonthNum int 
    DECLARE @WeekOfMonthDes varchar(10) 
    DECLARE @DayName varchar(10) 
    SELECT @nextDate = @startDate, @WeekOfMonthNum = DATEDIFF(week, DATEADD(MONTH, DATEDIFF(MONTH,0,@startDate),0),@startDate) + 1, 
    @WeekOfMonthDes = CASE @WeekOfMonthNum 
        WHEN '1' THEN 'First' 
        WHEN '2' THEN 'Second' 
        WHEN '3' THEN 'Third' 
        WHEN '4' THEN 'Fourth' 
        WHEN '5' THEN 'Fifth' 
        WHEN '6' THEN 'Sixth' 
        END, 
    @DayName 
    = DATENAME(weekday, @startDate)
SET @nextDay=1
WHILE @nextDate <= @endDate 
BEGIN 
    INSERT INTO @retValue values (@nextDay,@nextDate, @WeekOfMonthNum, @WeekOfMonthDes, @DayName) 
    SELECT @nextDay=@nextDay + 1 
SELECT @nextDate = DATEADD(day,1,@nextDate), 
    @WeekOfMonthNum 
    = DATEDIFF(week, DATEADD(MONTH, DATEDIFF(MONTH,0, @nextDate),0), @nextDate) + 1, 
    @WeekOfMonthDes 
    = CASE @WeekOfMonthNum 
    WHEN '1' THEN 'First' 
    WHEN '2' THEN 'Second' 
    WHEN '3' THEN 'Third' 
    WHEN '4' THEN 'Fourth' 
    WHEN '5' THEN 'Fifth' 
    WHEN '6' THEN 'Sixth' 
    END, 
    @DayName 
    = DATENAME(weekday, @nextDate) 
    CONTINUE 
END 

WHILE(@nextDay <=31)
BEGIN


    INSERT INTO @retValue values (@nextDay,@nextDate, 0, '', '') 
    SELECT @nextDay=@nextDay + 1

END

    RETURN
END

日付とのクロス結合を作成し、月と日付の比較を確認します。

于 2011-11-30T07:54:22.327 に答える
0

これがT-SQLであると仮定して、DATEPARTを使用して月と日付を別々に比較します。

http://msdn.microsoft.com/en-us/library/ms174420.aspx

または、全員の誕生日から現在の年の1月1日を引き、1900年(またはエポック年)を使用して比較します。

于 2008-09-17T14:07:13.207 に答える
0

別の考え:誕生日に通年の年齢を追加します(または、誕生日がまだ発生していない場合はもう1つ追加して、上記のように比較します。これを行うには、DATEPARTとDATEADDを使用します。

http://msdn.microsoft.com/en-us/library/ms186819.aspx

1年にわたる範囲のエッジケースには、特別なコードが必要です。

ボーナスのヒント:Birthdayオペランドを繰り返す代わりに、BETWEEN...ANDの使用を検討してください。

于 2008-09-17T14:13:41.333 に答える
0

これはうまくいくはずです...

DECLARE @endDate DATETIME
DECLARE @today DATETIME

SELECT @endDate = getDate()+6, @today = getDate()

SELECT * FROM Employees 
    WHERE 
    (DATEPART (month, birthday) >= DATEPART (month, @today)
        AND DATEPART (day, birthday) >= DATEPART (day, @today))
    AND
    (DATEPART (month, birthday) < DATEPART (month, @endDate)
        AND DATEPART (day, birthday) < DATEPART (day, @endDate))
于 2008-09-17T14:15:09.350 に答える
0

これは、テストされたいくつかの回答の組み合わせです。これは、特定の日付の後の次の誕生日と年齢を見つけます。また、numdays は、探している範囲を 7 日 = 週などに制限します。

SELECT DISTINCT FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1 age,
DATEADD(yyyy, FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1, Birthday) nextbirthday, birthday
FROM         table
WHERE     DATEADD(yyyy, FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1, Birthday) > @BeginDate  
AND DATEADD(yyyy, FLOOR(DATEDIFF(dd,Birthday, @BeginDate) / 365.25) + 1, Birthday) < DATEADD(dd, @NumDays, @BeginDate)
order by nextbirthday
于 2010-01-26T21:36:42.957 に答える
0

このチケットは何年も前にクローズされたと思いますが、正しい SQL クエリを取得するために、ぜひご覧ください。

SELECT Employee_Name, DATE_OF_BIRTH
FROM Hr_table 
WHERE 

/**
fetching the original birth_date and replacing the birth year to the current but have to  deduct 7 days to adjust jan 1-7 birthdate.
**/

datediff(d,getdate(),DATEADD(year,datediff(year,DATEADD(d,-7,hr.DATE_OF_BIRTH),getdate()),hr.date_of_birth)) between 0 and 7

-- current date looks ahead to 7 days for upcoming modified year birth date.

order by

-- sort by no of days before the birthday
datediff(d,getdate(),DATEADD(year,datediff(year,DATEADD(d,-7,hr.DATE_OF_BIRTH),getdate()),hr.date_of_birth))
于 2012-05-09T22:34:41.807 に答える
0

以下も使用できますDATEPART

-- To find out Today's Birthday
DECLARE @today DATETIME
SELECT  @today = getdate()

SELECT *
FROM SMIS_Registration 
WHERE (DATEPART (month, DOB) >= DATEPART (month, @today)
      AND DATEPART (day, DOB) = DATEPART (day, @today))
于 2015-07-31T11:40:17.583 に答える
0

DATE_FORMATを使用して、誕生日の日と月の部分を抽出できます。

編集: 申し訳ありませんが、彼が MySQL を使用していないことに気付きませんでした。

于 2008-09-17T14:01:31.317 に答える
0

これらのソリューションのほとんどは近いですが、いくつかの追加のシナリオを覚えておく必要があります。誕生日とスライディング スケールを使用する場合は、次の月への移行を処理できなければなりません。

たとえば、Stephens の例は、月の最後の 4 日間までの誕生日に最適です。次に、今日が 29 日である場合、有効な日付は次の月の 29、30、そして次の月の 1、2、3 になるため、論理エラーが発生するため、それについても条件を付ける必要があります。

代わりに、生年月日フィールドから日付を解析し、現在の年にサブしてから、標準的な範囲比較を行うこともできます。

于 2008-09-17T14:08:31.610 に答える
0

ナッツ!これについて考え始めてから、戻ってきて答えるまでの良い解決策です。:)

私が思いついた:

select  (365 + datediff(d,getdate(),cast(cast(datepart(yy,getdate()) as varchar(4)) + '-' + cast(datepart(m,birthdt) as varchar(2)) + '-' + cast(datepart(d,birthdt) as varchar(2)) as datetime))) % 365
from    employees
where   (365 + datediff(d,getdate(),cast(cast(datepart(yy,getdate()) as varchar(4)) + '-' + cast(datepart(m,birthdt) as varchar(2)) + '-' + cast(datepart(d,birthdt) as varchar(2)) as datetime))) % 365 < @NumDays

getdate() を日時としてキャストする必要はありませんよね?

于 2008-09-17T15:32:06.700 に答える
0

数年前、大学のプロジェクトで同じ問題に直面しました。私は、年と日付 (MM:DD) を 2 つの別々の列に分割することで (ややイタチ的な方法で) 応答しました。それ以前は、私のプロジェクト メイトは単にすべての日付を取得し、プログラムで調べていました。あまりにも非効率的だったので変更しましたが、私のソリューションがよりエレガントになったわけでもありません。また、複数のアプリでしばらく使用されているデータベースではおそらく実行できません。

于 2008-09-17T14:28:20.690 に答える
0

これを試してください:

SELECT * FROM Employees
WHERE DATEADD(yyyy, DATEPART(yyyy, @Today)-DATEPART(yyyy, Birthday), Birthday) > @Today 
AND DATEADD(yyyy, DATEPART(yyyy, @Today)-DATEPART(yyyy, Birthday), Birthday) < DATEADD(dd, @NumDays, @Today)
于 2008-09-17T14:39:11.523 に答える
0

同じことを達成する最良の方法は

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME

SELECT Member.* from vwMember AS Member  
WHERE (DATEADD(YEAR, (DATEPART(YEAR, @StartDate) -
                      DATEPART(YEAR, Member.dBirthDay)), Member.dBirthDay)
BETWEEN @StartDate AND @EndDate)
于 2010-03-11T14:00:13.047 に答える
0

このソリューションは、次の年の誕生日と順序も処理します: (dob = 誕生日; bty = 今年の誕生日; nbd = 次の誕生日)

with rs (bty) as (
    SELECT DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART(Year, dob), dob) as bty FROM Employees
),
rs2 (nbd) as (
  select case when bty < getdate() then DATEADD(yyyy, 1, bty) else bty end as nbd from rs
)
select nbd, DATEDIFF(d, getdate(), nbd) as diff from rs2 where DATEDIFF(d, getdate(), nbd) < 14 order by diff

日付の比較を回避するこのバージョンは、より高速になる可能性があります。

with rs (dob, bty) as (
    SELECT dob, DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART(Year, DOB), DOB) as bty FROM employee
),
rs2 (dob, nbd) as (
  select dob,  DATEADD(yyyy, FLOOR(ABS((-1*(SIGN(DATEDIFF(d, getdate(), bty))))+0.1)), bty) as nbd from rs
),
rs3 (dob, diff) as (
  select dob, datediff(d, getdate(), nbd) as diff from rs2
)
select dob, diff  from rs3 where diff < 14 order by diff

範囲が翌年の 2 月 29 日をカバーする場合は、次を使用します。

with rs (dob, ydiff) as (
  select dob, DATEPART(Year, GETDATE()) - DATEPART(Year, DOB) as ydiff from Employee
),
rs2 (dob, bty, ydiff) as (
  select dob, DATEADD(Year, ydiff, dob) as bty, ydiff from rs
),
rs3 (dob, nbd) as (
  select dob, DATEADD(yyyy, FLOOR(ABS((-1*(SIGN(DATEDIFF(d, getdate(), bty))))+0.1)) +  ydiff, dob) as nbd from rs2
),
rs4 (dob, ddiff, nbd) as (
  select dob, datediff(d, getdate(), nbd) as diff, nbd from rs3
)
select dob, nbd, ddiff from rs4 where ddiff < 68 order by ddiff
于 2015-07-03T14:18:36.903 に答える
0

これをMySQLに使用しました。おそらく最も効率的なクエリ方法ではありませんが、実装するのに十分単純です。

select * from `schema`.`table` where date_format(birthday,'%m%d') >= date_format(now(),'%m%d') and date_format(birthday,'%m%d') < date_format(DATE_ADD(NOW(), INTERVAL 5 DAY),'%m%d');
于 2012-01-06T17:48:37.673 に答える
0

従業員の誕生日 - Sqlserver

DECLARE @sam TABLE
(
    EmployeeIDs     int,
    dob         datetime
)
INSERT INTO @sam (dob, EmployeeIDs)
SELECT DOBirth, EmployeeID FROM Employee

SELECT *
FROM
(
    SELECT *, bd_this_year = DATEADD(YEAR, DATEPART(YEAR, GETDATE()) - DATEPART(YEAR, dob), dob)
    FROM @sam s
) d
WHERE d.bd_this_year > DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
AND d.bd_this_year <= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 3)
于 2008-12-01T07:40:17.253 に答える
-1
CREATE PROCEDURE [dbo].[P_EmployeesGetBirths]
        @Date Date,
        @Days int
    as
    Begin
        SET NOCOUNT ON;

        Declare
            @From int = Month(@Date) * 100 + Day(@Date),
            @To int = Month(DateAdd(DD, @Days, @Date)) * 100 + Day(DateAdd(DD, @Days, @Date)),
            @NeutralDate Date = Cast('1900-'+cast(Month(@Date) as nvarchar(2))+'-' + cast(Day(@Date) as nvarchar(2)) as Date)

        Select
            DOB,
            DATEADD(DD, DateDiff(DD, @NeutralDate, DateAdd(YY, 1900-Year(DOB), DOB)), @Date) OnDate
        From
            Employees(nolock)
        Where
            DOB is not null and
            Month(DOB) * 100 + Day(DOB) between @From and @To
        order by
            Month(DOB) * 100 + Day(DOB)
    End
    Go
于 2013-03-31T08:21:06.790 に答える
-1

今月の誕生日

SELECT * FROM tblMember m
WHERE m.GDExpireDate != '' 
AND CONVERT(CHAR(2),CONVERT(datetime, m.dob, 103), 101) = CONVERT(CHAR(2), GETDATE(), 101)    
AND CONVERT(CHAR(2),CONVERT(datetime, m.dob, 103), 103) >= CONVERT(CHAR(2), GETDATE(), 103)
于 2016-02-26T10:31:27.000 に答える
-1

私の解決策を試してください...私はInformixデータベースを持っています...

SELECT person, year(today)-year(birthdate) as years, birthdate,

CASE
WHEN MOD(year(birthdate)+((year(today)-year(birthdate))+1),4)<>0 AND MONTH(birthdate)=2 AND DAY(birthdate)=29 THEN 
   CASE 
   WHEN mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today >= 365 THEN (mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today)-365
   WHEN mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today < 365 THEN mdy(month(birthdate), 28, year(birthdate)+((year(today)-year(birthdate))+1))-today
   END
ELSE
   CASE 
   WHEN mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today >= 365 THEN (mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today)-365
   WHEN mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today < 365 THEN mdy(month(birthdate), day(birthdate), year(birthdate)+((year(today)-year(birthdate))+1))-today
   END
END until

FROM table_name
WHERE mdy(month(birthdate), day(birthdate), 2000) >= mdy(month(today), day(today), 2000)
AND mdy(month(birthdate), day(birthdate), 2000) <= mdy(month(today), day(today), 2000)+30
OR
mdy(month(birthdate), day(birthdate), 2000) <= mdy(month(today), day(today), 2000)-(365-30)
ORDER BY 4, YEAR(birthdate)
于 2010-12-04T09:33:27.780 に答える
-2

より良い、年の差を BIRTHDAY の日付に追加して、今年のすべてを作成してから、比較を行います

SELECT * FROM Employees WHERE
  DATEADD ( year, YEAR(@Today) - YEAR(@Birthday), birthday) BETWEEN @Today AND @EndDate
于 2008-09-17T14:02:33.577 に答える