2012-03-27 11 views
18

Prawdopodobnie jest to proste, gdy klauzula, ale chcę powiedzieć, ze columnX (co jest datetime) Chcę wszystkich wierszy, gdzie tylko rok = 2010SQL select * from kolumnie gdzie rok = 2010

tak:

select * from mytable where Columnx = 
+0

jakieś dodatkowe informacje: http://stackoverflow.com/questions/7870943/how-efficient-is-the-yeardate-function – Simon

Odpowiedz

26
select * from mytable where year(Columnx) = 2010 

Odnośnie użycia indeksu (odbiera komentarz Szymona):

jeśli masz indeksu na Columnx, SQLServer NIE używać go w przypadku korzystania z funkcji „rok” (lub jakiejkolwiek innej funkcji).

Są to dwa możliwe rozwiązania, jeden wykonuje wyszukiwanie według przedziałów takich jak Columnx> = '01012010' i Columnx < = '31122010', a drugi służy do tworzenia kolumny obliczeniowej z wyrażeniem year (Columnx), indeks go, a następnie wykonaj filtr na tej nowej kolumny

+0

Jeśli wydajność nie jest do zera, myślę, że ta metoda nie korzysta z żadnych indeksów w kolumnie "Columnx" – Simon

+1

@imon - Masz rację, zawijanie kolumny w funkcji sprawia, że ​​nie można jej sansować. Powoduje to pełne skanowanie. Nigdy bym tego nie zrobił. Jest to bardzo słaba praktyka w przypadku filtrowania dat. Gorąco polecam OP patrzy na twoją odpowiedź. – MatBailie

+0

Hi @simon, dzięki za komentarz, dodałem więcej wyjaśnień w tej sprawie. Po prostu nie robiłem tego wcześniej, ponieważ ponieważ OP ma bardzo proste problemy z funkcją Year(), nie wyobrażałem sobie, że martwiłby się o używanie indeksów w tym momencie. – Diego

5

T-SQL i inne;

select * from t where year(Columnx) = 2010 
+3

Owijanie kolumnę w funkcji sprawia, że ​​nie sargable . Powoduje to pełne skanowanie. Nigdy bym tego nie zrobił. Jest to bardzo słaba praktyka w przypadku filtrowania dat. Bardzo polecam OP patrzy na odpowiedź @simon. – MatBailie

21

Jeśli dobrze rozumiem, że chcesz wszystkie wiersze w roku 2010, a następnie:

select * 
    from mytable 
where Columnx >= '2010-01-01 00:00:00' 
     and Columnx < '2011-01-01 00:00:00' 
+2

+1 - Czy to, co OP chce? *** i *** korzysta z indeksów dla poszukiwań zasięgu, które mogą być o rząd wielkości szybsze niż inne dotychczasowe odpowiedzi. – MatBailie

+3

Tak, +1 za zezwolenie na użycie indeksów.Możesz także uprościć warunek do: 'where Columnx> = '2010-01-01' i Columnx <'2011-01-01'' (bez żadnej różnicy w wydajności, tylko kilka znaków kodu mniej :) –

1

jej tylko proste

select * from myTable where year(columnX) = 2010 
+1

Owijanie kolumna w funkcji sprawia, że ​​nie można jej sansować. Powoduje to pełne skanowanie. Nigdy bym tego nie zrobił. Jest to bardzo słaba praktyka w przypadku filtrowania dat. Bardzo polecam OP patrzy na odpowiedź @simon. – MatBailie

0

NB: Jeżeli chcesz roku opierać się na jakimś dniu referencyjnym, kod poniżej oblicza daty na rachunku between:

declare @referenceTime datetime = getutcdate() 
select * 
from myTable 
where SomeDate 
    between dateadd(year, year(@referenceTime) - 1900, '01-01-1900')      --1st Jan this year (midnight) 
    and dateadd(millisecond, -3, dateadd(year, year(@referenceTime) - 1900, '01-01-1901')) --31st Dec end of this year (just before midnight of the new year) 

Podobnie, jeśli używasz wartości roku, zamiana year(@referenceDate) dla Twojego rokiem odniesienia jest wartość zadziała

declare @referenceYear int = 2010 
select * 
from myTable 
where SomeDate 
    between dateadd(year,@referenceYear - 1900, '01-01-1900')      --1st Jan this year (midnight) 
    and dateadd(millisecond, -3, dateadd(year,@referenceYear - 1900, '01-01-1901')) --31st Dec end of this year (just before midnight of the new year)