2010-04-06 10 views
33

w SQL 2005, zamiast budować zapytania z dateparts rok, miesiąc i dzień,Get wiersz gdzie datetime kolumna = dzisiaj - SQL Server noobem

jest tam bardziej zwięzły sposób pisania klauzuli WHERE?

+0

Zastanawiam się, czy któraś z odpowiedzi jest już bardziej zwięzła. Uważam, że jest to również bardziej czytelne. gdzie (DATEPART (yy, myColum) = '2010') ORAZ (DATEPART (mm, myColum) = '4') ORAZ (DATEPART (dd, myColum) = '7'); – Chin

+1

** @ Chin, twoja metoda zapobiegnie używaniu indeksu i spowoduje powolne skanowanie tabeli. ** Gorąco polecam, abyś NIGDY nie wyszukiwał w oparciu o datę przy użyciu tej metody. Musisz "posadzić" daty w zakresie i nie stosować żadnych funkcji w kolumnie, jeśli chcesz użyć indeksu. w ten sposób można posadzić datetime: http://stackoverflow.com/questions/85373/floor-a-date-in-sql-server –

+0

@KM, dzięki za to. Myślałem, że zapytam i zobaczę, czy jestem poza bazą. Obecnie nie jestem świadomy indeksu w tej kolumnie. Będę o tym pamiętać i piętro moich dat, jak zasugerowałeś. – Chin

Odpowiedz

22

W SQL 2000 i SQL 2005 można użyć piękny SELECT, aby usunąć składnik czasu z DateTime, czyli

SELECT DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0) 

powróci 6 -Apr-2010 (również na dziś tylko).

Więc w połączeniu z odpowiedzią marc_s koszula, którą chcesz

SELECT (list of fields) 
FROM dbo.YourTable 
WHERE dateValue BETWEEN DATEADD(dd, DATEDIFF(dd,0,'MY Date and Time, But I Only Want Date'), 0) 
AND DATEADD(dd, DATEDIFF(dd,0,'MY Date and Time, But I Only Want Date'), 1) 

Edycja: Zmieniono do wymagań, zanotuj 1 w drugim DateAdd (to dodaje dni to było od początku do 1 (zamiast z 0), co czyni go 07 kwietnia 2010 00:00:00) Jeśli chcesz 06 kwiecień 23:59:59 wziąć drugi od drugiego terminu

DATEADD(ss,-1,'My DateTime') 

Final Call staną

DATEADD(ss,-1,DATEADD(dd, DATEDIFF(dd,0,'MY Date and Time, But I Only Want Date'), 1)) 

OK, to mnóstwo informacji naraz! Nadzieję, że to wszystko ma sens :)

+0

Podoba mi się twoja ekspresja, aby część z datą była lepsza niż moje rozwiązanie - ale ten wybór nie zadziała, nie ?? Jeśli masz "2010-04-06 15:15:15" - jak porównanie tego do części daty wybiera? Myślę, że potrzebujesz wartości "WHERE dateVALue BETWEEN (today) AND (today + 1 day)", aby pobrać wszystkie te wartości dzisiaj z dołączoną częścią czasową ... –

+1

Jeśli chcesz całkowicie zniszczyć indeksy , możesz użyć DateAdd/DatePart na DateValue, ale to zły pomysł! (Jeśli masz dobre indeksy :)) – PostMan

+0

Miałem czasy, które są między 23: 59: 59.000 i 00: 00: 00.000 następnego dnia wyeliminowane z raportów. więc nigdy nie użyłbym "odejmij jedną drugą metodę". Lepiej jest zachować czas o 00: 00: 000.000 i zwiększać jeden dzień i po prostu użyć "<" mniej niż (twoja kolumna

25

na SQL Server 2008, można mieć nowy typ DATE danych, które można wykorzystać do osiągnięcia tego celu:

SELECT (list of fields) 
FROM dbo.YourTable 
WHERE dateValue BETWEEN 
    CAST(GETDATE() AS DATE) AND DATEADD(DAY, 1, CAST(GETDATE() AS DATE)) 

CAST(GETDATE() AS DATE) rzuca bieżącą datę i czas do wartości data-only, np return "2010-04-06" dla 6 kwietnia 2010. Dodanie jednego dnia do tego zasadniczo wybiera wszystkie dzisiejsze wartości datetime.

W SQL Server 2005, nie ma łatwego sposobu, aby to zrobić - najbardziej eleganckie rozwiązanie I found here korzysta numeryczną manipulacji datetime, aby osiągnąć ten sam rezultat:

SELECT (list of fields) 
FROM dbo.YourTable 
WHERE dateValue BETWEEN 
    CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME) AND 
    DATEADD(DAY, 1, CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)) 
+0

@marc_s - czy właśnie usunąłeś swoją odpowiedź? przeraził mnie, gdy próbowałem dodać komentarz. Jeśli tylko ulepszę CUC. Dziękuję za pomoc, ale bardzo doceniam. – Chin

+0

@Chin: tak, najpierw miałem głupią odpowiedź, usunąłem ją, zredagowałem i ponownie usunąłem :-) –

+0

@marc_s: Na pewno masz obłąkaną definicję słowa "elegancki", +1 :) –

1

coś na wzór tego

CONVERT(date,tbldata.date)=CONVERT(date,getdate()) 

Zakłada się, że kolumna z datą również zawiera czas. Jeśli nie, to możesz go zmienić na

tbldata.date=CONVERT(date,getdate()) 
+0

Sql Server 2005 ma typ "date"? ;) –

+0

Okazuje się, że tak nie jest. Mój obecny stack to SQL Server 2008, który minął jakiś czas od momentu aktualizacji i założyłem, że w 2005 r. Ta funkcja jest dostępna. –

4

nie dobre osiągi, ale rozwiązanie:

SELECT * 
FROM tblDate 
WHERE CONVERT(VARCHAR, date, 112) = CONVERT(VARCHAR, GETDATE(), 112); 

Jeśli jest to powszechne kwerendy kolumna obliczana należy dodać tylko zawartości rok-miesiąc-dzień.

+0

masz rację, będzie to powolne, ponieważ żaden indeks nie będzie użyty –

0

Użyłem UDF to zrobić na kolumnach datetime wraca do SQL 2000.

CREATE FUNCTION [dbo].[GETDATENOTIME](@now datetime) 
RETURNS smalldatetime 
AS 
BEGIN 
    RETURN (CONVERT(smalldatetime, CONVERT(varchar, @now, 112))) 
END 

Zastosowanie:

DECLARE @date smalldatetime 
SET @date = '4/1/10' 
SELECT * FROM mytable WHERE dbo.GETDATENOTIME(date) = @date 

Nie jest to najbardziej efektywny rzeczą na świecie (w zależności od YMMV twój stół), ale spełnia swoją rolę.W przypadku tabel, o których wiem, że będę wybierał na podstawie daty bez czasu, będę miał kolumnę specjalnie dla tego z domyślnym ustawieniem na dbo.GETDATENOTIME (GETDATE()).

+1

jeśli kiedykolwiek miałeś indeks w kolumnie "data", to na pewno nie będziesz w stanie z niego skorzystać, a zatem wynik skanowania tabeli ... –

+0

Stąd moje zastrzeżenie na końcu. OP poprosił o zwięzłą składnię, więc to jest odpowiedź, którą mu dałem. – Dane