Belirli bir aydaki tüm kayıtları bulmak için NEREDE Maddesi


87

Bir Ay ve Yıl saklı bir yordamı verebilmek ve o ayda olan her şeyi geri vermesini istiyorum, bazı ayların farklı gün sayıları olduğu için bunu karşılaştıramayacağım için bunu nasıl yapabilirim?

Bunu yapmanın en iyi yolu nedir? Sadece yıl ve ay bazında karşılaştırma isteyebilir miyim?

Teşekkürler.

Yanıtlar:


186

Sanırım aradığınız işlev MONTH(date). Muhtemelen "YIL" ı da kullanmak isteyeceksiniz .

Şöyle thingsgörünen bir tablonuz olduğunu varsayalım :

id happend_at
-- ----------------
1  2009-01-01 12:08
2  2009-02-01 12:00
3  2009-01-12 09:40
4  2009-01-29 17:55

Ve diyelim ki happened_at2009/01 (Ocak 2009) ayı boyunca a olan tüm kayıtları bulmak için yürütmek istiyorsunuz . SQL sorgusu şöyle olacaktır:

SELECT id FROM things 
   WHERE MONTH(happened_at) = 1 AND YEAR(happened_at) = 2009

Hangi geri döner:

id
---
1
3
4

14
Aslında ! İlgilenen herkes için "GÜN, AY ve YIL işlevleri sırasıyla DATEPART (gg, tarih), DATEPART (mm, tarih) ve DATEPART (yy, tarih) ile eşanlamlıdır."
Tarks

17

Yanıtların çoğunda önerildiği gibi AY ve YIL işlevlerini kullanmak, SQL Server'ın tarih sütununuzda olabilecek herhangi bir dizini kullanamaması dezavantajına sahiptir. Bu, büyük bir masadaki performansı öldürebilir.

İlgilendiğiniz ayın ilk gününü temsil eden saklı yordama bir DATETIME değeri (örn. @StartDate) iletme eğilimindeyim.

Daha sonra kullanabilirsiniz

SELECT ... FROM ...
WHERE DateColumn >= @StartDate 
AND DateColumn < DATEADD(month, 1, @StartDate)

Ayı ve yılı saklı yordama ayrı parametreler olarak geçirmeniz gerekiyorsa, CAST ve CONVERT kullanarak ayın ilk gününü temsil eden bir DATETIME oluşturabilir ve ardından yukarıdaki gibi devam edebilirsiniz. Bunu yaparsanız, tamsayı yıl, ay, gün değerlerinden bir DATETIME oluşturan bir işlev yazmanızı tavsiye ederim, örneğin bir SQL Server blogundan aşağıdaki gibi .

create function Date(@Year int, @Month int, @Day int)
returns datetime
as
    begin
    return dateadd(month,((@Year-1900)*12)+@Month-1,@Day-1)
    end
go

Ardından sorgu şu hale gelir:

SELECT ... FROM ...
WHERE DateColumn >= Date(@Year,@Month,1)
AND DateColumn < DATEADD(month, 1, Date(@Year,@Month,1))

1
Ya @joe'ya katılıyorum "AY ve YIL işlevlerini yanıtların çoğunda önerildiği gibi kullanmak, SQL Server'ın tarih sütununuzda olabilecek herhangi bir dizini kullanamaması dezavantajına sahiptir. Bu, büyük bir tablodaki performansı öldürebilir. . "
Raghav

Bir şey ekleyebilir miyim? Bir parametrede '@StartDate'i bildiriyorsanız, SQL'in her satırda matematik işlemlerini yapması yerine, @EndDate'i de bildirir ve DATEADD'yi oraya yerleştiririm.
DataGirl

@DataGirl - ilginç nokta. DATEADD işlevinin çalışma zamanı sabiti olarak değerlendirileceğini ve yalnızca bir kez değerlendirileceğini varsaydım. Bu konuda bir şüphe varsa, beyan @EndDateetmek onu açık hale getirecektir.
Joe

4

Daha fazla ipucu çok basit. Ayrıca to_char işlevini de kullanabilirsiniz , bakın:

Ay için:

to_char ( oldu_at , 'MM') = 01

Yıl için:
to_char ( oldu_at , 'YYYY') = 2009

Gün için:

to_char ( oldu_at , 'DD') = 01

to_char işlevi, belirli bir veritabanı tarafından değil, sql dili tarafından desteklenir.

Umarım birine daha fazla yardım eder ...

Abs!


1
Bunun yalnızca Oracle için çalıştığı izlenimine sahibim, gerçekten spesifik. SQL Server kesinlikle desteklemiyor.
Carol

3

MONTH ve YEAR işlevlerine alternatif olarak, normal bir WHERE yan tümcesi de çalışacaktır:

select *
from yourtable
where '2009-01-01' <= datecolumn and datecolumn < '2009-02-01'


1

Sadece yıl ve ay bazında karşılaştırma isteyebilir miyim?

Yapabilirsin. İşte AdventureWorks örnek veritabanını kullanan basit bir örnek ...

DECLARE @Year       INT
DECLARE @Month      INT

SET @Year = 2002
SET @Month = 6

SELECT 
    [pch].* 
FROM 
    [Production].[ProductCostHistory]   pch
WHERE
    YEAR([pch].[ModifiedDate]) = @Year
AND MONTH([pch].[ModifiedDate]) = @Month

1

Geçici veri türü olarak bir değeri iletmeyi daha kolay buluyorum (örneğin DATETIME), daha sonra özellikle geçici işlevselliği kullanıyorum DATEADDve DATEPARTdönemin başlangıç ​​ve bitiş tarihlerini bulmak için, bu durumda ay, ör. Başlangıç ​​tarihi ve bitiş tarihi çiftini bulur geçerli ay için, sadece CURRENT_TIMESTAMPsizin için türünde bir parametreyi kullanın DATETIME(1990-01-01 değerinin tamamen keyfi olduğunu unutmayın):

SELECT DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-01T00:00:00.000'), 
       DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-31T23:59:59.997')

0

Bunun gibi bir şey yapmalı:

select * from yourtable where datepart(month,field) = @month and datepart(year,field) = @year

Alternatif olarak, kaydı oluştururken ayı ve yılı kendi sütunlarına ayırabilir ve ardından bunlara karşı seçim yapabilirsiniz.

Iain


0

Bunun bir yolu, ayın ilkini (yani 5/1/2009) temsil eden bir değişken oluşturmak, onu proc'a geçirmek veya oluşturmak (ay / 1 / yıl birleştirme) olabilir. Ardından DateDiff işlevini kullanın.

WHERE DateDiff(m,@Date,DateField) = 0

Bu, eşleşen ay ve yıla sahip her şeyi döndürür.


-4
SELECT * FROM yourtable WHERE yourtimestampfield LIKE 'AAAA-MM%';

AAAAİstediğin yıl nerede ve istediğin MMay

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.