it-swarm-tr.com

SQL Yaklaşan Doğum Günlerini Seçin

Yaklaşan doğum günleri olan çalışanları seçmek için saklı bir prosedür yazmaya çalışıyorum.

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

Bu işe yaramayacak çünkü doğum yılı Doğum Günü'nin bir parçası, eğer doğum günüm '09-18-1983' ise, '09 -18-2008' ile '09 -25-2008' arasında kalmayacak.

Tarih alanlarının yıl bölümünü yoksaymanın ve sadece ay/günleri karşılaştırmanın bir yolu var mı?

Bu her pazartesi sabahı gelecek doğum günlerinin yöneticilerini uyaracak, bu yüzden muhtemelen yeni yıllara yayılacak.

İşte yarattığım çalışma çözümü, teşekkürler Kogus.

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

Not: Önemli bir hata olduğuna inandığım şeyi düzeltmek için bunu düzenledim. Şu anda yayınlanan sürüm benim için çalışıyor.

Bu, alan ve tablo adlarını veritabanınıza karşılık gelecek şekilde değiştirdikten sonra çalışmalıdır.

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

Temel olarak, doğum günlerinden bugüne günlerin sayısını alır ve bunu 365'e böler (doğrudan yıllara dönüştürdüğünüzde ortaya çıkan yuvarlama sorunlarını önlemek için).

Daha sonra doğum günlerinden bir hafta öncesine kadar olan günlerin sayısını alır ve bundan bir hafta sonra yaşlarını almak için bunu 365'e böler.

Doğum günleri bir hafta içinde ise, bu iki değer arasındaki fark 1 olacaktır. Böylece tüm bu kayıtları döndürür.

30
JosephStyons

Birisinin hala MySQL (biraz farklı komutlar) içinde bir çözüm aradığı durumda, burada sorgusu:

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)
12
Andres SK

Datediff ve dateadd'ın en iyi kullanımı. Yuvarlama yok, yaklaşık yok, 29 şubat böceği yok, tarih fonksiyonlarından başka bir şey yok

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

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

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

@Gustavo Cardoso'ya teşekkürler, kişinin yaşı için yeni tanım

  1. ageOfThePerson = FLOOR(DATEDIFF(d,dateOfBirth, GETDATE())/365.25)
8

@Strelc'in yaklaşımını sevdim, fakat onun sql'si biraz kapalıydı. İşte iyi çalışan ve kullanımı basit bir güncellenmiş sürümü:

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

10/2017 düzenle: bitiş için tek bir gün ekle

3
Edyn

Bunun için çözümü buldum. Bu birinin değerli zamanını kurtarabilir.

 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 @[email protected] + 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 @[email protected] + 1

END

    RETURN
END

Tarihlerle bir haç yapın ve ay ile tarihlerin karşılaştırmasını kontrol edin.

2
Jovial

DAYOFYEAR işlevini kullanabilirsiniz, ancak Aralık ayında Ocak doğum günlerini aramak istediğinizde dikkatli olun. Sanırım aradığınız tarih aralığı Yeni Yılı yaymadığı sürece iyi olacaksınız.

2
Dave Webb

Tahminim, "365.25" i çok yakında kullanıyorsa başarısız olur.

Bu nedenle çalışma çözümünü "365.25" kullanarak test ediyorum ve Her durum için aynı sayıda satırı döndürmüyorum. İşte bir örnek:

http://sqlfiddle.com/#!3/94c3ce/7

yıl 2016 ve 2116 ile test ve farkı göreceksiniz. Yalnızca bir bağlantı gönderebilirim/her ikisini de sorgulamak için de/7// 8 ile değiştirebilirim. (İlk cevap için/10 ve/11)

Bu yüzden, bir sonraki sorgunun başlangıç ​​tarihinden itibaren bir sonraki doğum gününü belirlediği bir sorguyu daha sonra öneririm ve ilgilendiğim aralıkta ise karşılaştırın.

SELECT * FROM Employees 
WHERE 
CASE WHEN (DATEADD(yyyy,DATEDIFF(yyyy, birthdt, @fromDate),birthdt) < @fromDate )
THEN DATEADD(yyyy,DATEDIFF(yyyy, birthdt, @fromDate)+1,birthdt)
ELSE DATEADD(yyyy,DATEDIFF(yyyy, birthdt, @fromDate),birthdt) END
BETWEEN @fromDate AND @toDate
2
Fede H

Maalesef yılı etkisiz hale getirme gereğini görmedim.

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)

Bu çalışmalı.

2
Nick Berardi

Bir aydan az bir sürede:

SELECT * FROM people WHERE MOD( DATEDIFF( CURDATE( ) , `date_birth`) /30, 12 ) <1 and (((month(`date_birth`)) = (month(curdate())) and (day(`date_birth`)) > (day (curdate() ))) or ((month(`date_birth`)) > (month(curdate())) and (day(`date_birth`)) < (day (curdate() ))))
1
Danilo

Bu, MS SQL Server için bir çözümdür: Doğum günleri olan çalışanları 30 gün içinde iade eder.

SELECT * FROM rojstni_dnevi
  WHERE (DATEDIFF   (dd, 
                    getdate(), 
                    DATEADD (   yyyy, 
                                DATEDIFF(yyyy, rDan, getdate()),
                                rDan)
    nex             )
        +365) % 365 < 30
1
strelc

Bunu MySQL için kullandım, muhtemelen sorgulamanın en etkili yolu değil, uygulaması basit.

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');
0
Xocoatzin

DATEPART öğesini de kullanabilirsiniz:

-- 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))
0
Raj Sharma

Bu çözüm, gelecek yıl doğum günleri ve siparişleri de dikkate alır: (dob = doğum günü; bty = bu yıl doğum günü; nbd = sonraki doğum günü)

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

Tarihlerin karşılaştırılmasını engelleyen bu sürüm daha hızlı olabilir:

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

Aralık, gelecek yıl 29 Şubat’ı kapsıyorsa, şunları kullanın:

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
0
Pilso

Daha iyi ve kolay çözüm:

select * from users with(nolock)
where date_of_birth is not null 
and 
(
      DATEDIFF(dd,
                  DATEADD(yy, -(YEAR(GETDATE())-1900),GETDATE()), --Today
                  DATEADD(yy, -(YEAR(date_of_birth)-1901),date_of_birth)
      ) % 365
) = 30
0
AjitChahal

birthDate'i seçin, Çalışanlar adına göre sırayla Case WHEN dönüşümü (nvarchar (5), BirthDate, 101)> convert (nvarchar (5), GETDATE (), 101) sonra 2 WHEN dönüşümü (nvarchar (5), BirthDate, 101) < dönüştürmek (nvarchar (5), GETDATE (), 101) sonra 3 WHEN dönüştürmek (nvarchar (5), BirthDate, 101) = dönüştürmek (nvarchar (5), GETDATE (), 101) sonra 1 başka 4 son, dönüştürmek (nvarchar (2), doğum tarihi, 101) dönüştürmek (nvarchar (2), doğum tarihi, 105)

0

Cari ay doğum günü

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)
0
Bhavesh Patel

Fındık! Bunu düşünmeye başladığımda ve cevaplamaya geri döndüğümde iyi bir çözüm. :)

Ben geldim:

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 () 'yi bir tarih olarak kullanmanız gerekmez, değil mi?

0
clweeks

Doğum tarihlerinin gün ve ay bölümlerini çıkarmak için DATE_FORMAT kullanabilirsiniz.

EDIT: üzgünüm MySQL kullanmadığını görmedim.

0
p4bl0

Aynı elde etmenin en iyi yolu

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)
0
Ramandeep Singh

Aynı problemi birkaç yıl önce üniversite projemle de karşıladım. Yıl ve tarihi (MM: DD) iki ayrı sütuna bölerek (oldukça zayıf bir şekilde) cevap verdim. Ve bundan önce, proje arkadaşım sadece bütün tarihleri ​​almaktı ve programatik olarak onlardan geçiyordu. Bunu değiştirdik, çünkü bu çok verimsizdi - benim çözümümün daha da zarif olması değildi. Ayrıca, bir süredir çoklu uygulamalar tarafından kullanılmakta olan bir veritabanında yapılması da mümkün değildir.

0
Mostlyharmless

Bu, test edilen cevapların birkaçının birleşimidir. Bu, bir sonraki brithday’i belirli bir tarihten ve yaşa girecekleri günden sonra bulacak. Ayrıca numdays, aradığınız aralığı 7 gün = hafta vb. Sınırlar.

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
0
Kyle

Çözüm SQLite:

SELECT
    *, 
    strftime('%j', birthday) - strftime('%j', 'now') AS days_remaining
FROM
    person
WHERE :n_days >= CASE
    WHEN days_remaining >= 0 THEN days_remaining
    ELSE days_remaining + strftime('%j', strftime('%Y-12-31', 'now'))
    END
;

Yaşı almak için doğum tarihini 325.25'e bölen veya doğum tarihini şimdiki yıla vb. Getiren çözümler benim için işe yaramadı. Bu, iki günün deltalarını hesaplar. TheYear'ın (1-366). Doğum günü henüz bu yıl gerçekleşmediyse, karşılaştırabileceğiniz doğru gün sayısını otomatik olarak alırsınız. Doğum günü zaten olmuşsa, kalan günler negatiftir ve geçerli yıldaki toplam gün sayısını ekleyerek kalan gün sayısını doğru alabilirsiniz. Bu aynı zamanda artık yılları da doğru şekilde işler, çünkü bu durumda fazladan bir gün de eklenir (dayOfYear kullanarak (Aralık 31.))

0
smoothware

bu biletin yıllar önce kapatıldığına inanıyorum, ancak doğru sql sorgusunu elde etmek için lütfen bir göz atın.

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))
0
maSTAShuFu

Sorgunun altında çalışanın tüm doğum gününü döndürecek, en kısa sorgudur.

SELECT 
    Employee.DOB,
    DATEADD(
                mm, 
                (
                    (
                        (
                            (
                                DATEPART(yyyy, getdate())-DATEPART(yyyy, Employee.DOB )
                            )
                            +
                            (
                                1-
                                (
                                    ((DATEPART(mm, Employee.DOB)*100)+DATEPART(dd, Employee.DOB))
                                    /
                                    ((DATEPART(mm, getdate())*100) + DATEPART(dd, getdate()))
                                )
                            )
                        )
                    *12
                    )
                ), 
                Employee.DOB
            ) NextDOB
FROM 
    Employee 
ORDER BY 
    NextDOB ;

Yukarıdaki sorgu, geçerli tarih hariç tüm gelecek ayları kapsayacak.

0
Paresh Patel

Bunun T-SQL olduğunu varsayarak, ayı ve tarihi ayrı olarak karşılaştırmak için DATEPART kullanın.

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

Alternatif olarak, bu yılın 1 Ocak tarihini herkesin doğum gününden çıkarın ve 1900 yılını (veya Epoch yılınız ne olursa olsun) kullanarak karşılaştırın.

0

Bu çözümlerin çoğu yakın, ancak birkaç ilave senaryoyu hatırlamanız gerekiyor. Doğum günleri ve kayan bir ölçekle çalışırken, bir sonraki aya geçişi gerçekleştirebilmelisiniz.

Örneğin Stephens örneği, doğum günleri için ayın son 4 gününe kadar harika çalışır. Öyleyse, eğer 29'unda bugün olsaydı geçerli tarihler olarak bir mantık arızası yaşarsınız: 29, 30, VE SONRAKİ ayın 1, 2, 3'ü.

Bir alternatif doğum günü alanından tarih ayrıştırmak ve cari yıl alt, sonra standart bir aralık karşılaştırması yapmak olacaktır.

0
Mitchel Sellers

Başka bir düşünce: Yaşlarını bütün yıllar içinde doğum günlerine ekleyin (veya Doğum günleri henüz gerçekleşmediyse bir tane daha yapın ve sonra yukarıda yaptığınız gibi karşılaştırın. Bunu yapmak için DATEPART ve DATEADD kullanın.

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

Yılı kapsayan bir aralıktaki Edge durumunun özel bir kodu olması gerekir.

Bonus ipucu: Birthday operandını tekrarlamak yerine BETWEEN ... AND kullanmayı düşünün.

0

Bunu bir deneyin:

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)
0
Esteban Brenes

Bu çalışmalı...

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))
0
bastos.sergio

Umarım bu size bir şekilde yardımcı olur ....

select Employeename,DOB 
from Employeemaster
where day(Dob)>day(getdate()) and month(DOB)>=month(getDate())
0
Bharathi

Çalışan için Yaklaşan Doğum Günü - 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)
0
samdoss