Jak zapytać o pole DATETIME, używając tylko daty w Microsoft SQL Server?


88

Mam tabelę TEST z DATETIMEpolem takim jak ta:

ID NAME DATE
1 TESTING 2014-03-19 20:05:20.000

Czego potrzebuję zapytania zwracającego ten wiersz i każdy wiersz z datą 19.03.2014, bez względu na godzinę. Próbowałem użyć

select * from test where date = '03/19/2014';

Ale nie zwraca żadnych wierszy. Jedynym sposobem, aby to zadziałało, jest podanie godziny w dacie:

select * from test where date = '03/19/2014 20:03:02.000';

Odpowiedzi:


126

użyj zakresu lub funkcji DateDiff

 select * from test 
 where date between '03/19/2014' and '03/19/2014 23:59:59'

lub

 select * from test 
 where datediff(day, date, '03/19/2014') = 0

Inne opcje to:

  1. Jeśli masz kontrolę nad schematem bazy danych i nie potrzebujesz danych dotyczących czasu, usuń je.

  2. lub, jeśli musisz go zachować, dodaj obliczony atrybut kolumny, w którym część czasu z wartości daty została usunięta ...

Alter table Test Add DateOnly As DateAdd(day, datediff(day, 0, date), 0)

lub w nowszych wersjach programu SQL Server ...

Alter table Test Add DateOnly As Cast(DateAdd(day, datediff(day, 0, date), 0) as Date)

następnie możesz napisać zapytanie w prosty sposób:

select * from test 
where DateOnly = '03/19/2014'

Ok, to działa, ale zastanawiałem się, czy istnieje prostszy sposób.
delphirules

Cóż, jedynym innym łatwiejszym sposobem jest nie umieszczanie danych dotyczących czasu w bazie danych w pierwszej kolejności ... lub tworzenie obliczonego atrybutu, który usuwa część czasu i używa go ... Dodałem obie opcje do mojej odpowiedzi.
Charles Bretana,

Obawiałem się, że metoda DATEDIFF zwróci prawdę (niepożądanie) dla dat takich jak 19.04.2014 lub 19.03.2015, ponieważ część `` dzień '' tych dat jest taka sama (a gdzie indziej widziałem raporty, że działają w ten sposób), ale przetestowałem to z bazą danych i wydaje się, że działa poprawnie.
mono código

Tak, ponieważ DateDiff()funkcja we wszystkich swoich wariantach oblicza i zwraca liczbę granic dat, które należy przekroczyć, aby uzyskać frlom jedną datę do drugiej. Dlatego DateDiff(day, '1Jan2016', '31Dec2017 23:259:59')i DateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') oboje wracają 1.
Charles Bretana

55

Prosta odpowiedź;

select * from test where cast ([date] as date) = '03/19/2014';

Chociaż jest to prawidłowa odpowiedź, chcę zwrócić uwagę, że umieszczenie wartości pola daty za jakąkolwiek funkcją doprowadzi do problemów z wydajnością. Każdy indeks daty będzie bezużyteczny, a silnik będzie musiał ocenić każdy wiersz
jean


7
select * from test 
where date between '03/19/2014' and '03/19/2014 23:59:59'

To naprawdę zła odpowiedź. Z dwóch powodów.

1. Co dzieje się z czasami 23.59.59.700 itd. Są czasy większe niż 23:59:59 i następny dzień.

2. Zachowanie zależy od typu danych. Zapytanie zachowuje się inaczej w przypadku typów datetime / date / datetime2.

Testowanie z 23: 59: 59.999 sprawia, że ​​jest jeszcze gorzej, ponieważ w zależności od typu danych otrzymujesz różne zaokrąglenia.

select convert (varchar(40),convert(date      , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime  , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime2 , '2014-03-19 23:59:59.999'))

- W przypadku daty wartość jest „posiekana”. - W przypadku daty i godziny wartość jest zaokrąglana w górę do następnej daty. (Najbliższa wartość). - Dla datetime2 wartość jest dokładna.


7

To działa dla mnie na serwerze MS SQL:

select * from test
where 
year(date) = 2015
and month(date) = 10
and day(date)= 28 ;

1

Spróbuj tego

 select * from test where Convert(varchar, date,111)= '03/19/2014'

1

możesz tego spróbować

select * from test where DATEADD(dd, 0, DATEDIFF(dd, 0, date)) = '03/19/2014';

1
Dziękuję, ale myślę, że prostszym rozwiązaniem byłoby porównanie z czasem, tak jak poprzednie rozwiązanie.
delphirules

0

Możesz użyć tego podejścia, które skraca część czasu:

select * from test
where convert(datetime,'03/19/2014',102) = DATEADD(dd, DATEDIFF(dd, 0, date), 0)

0
-- Reverse the date format
-- this false:
    select * from test where date = '28/10/2015'
-- this true:
    select * from test where date = '2015/10/28'

1
Dodaj wyjaśnienie do swojej odpowiedzi!
ρss

To nie działa, ponieważ „2015/10/28 00: 00.001” różni się od „2015/10/28”
PedroC88

0

Po prostu użyj tego w swojej WHEREklauzuli.

Część „SubmitDate” poniżej to nazwa kolumny, więc wstaw własną.

Spowoduje to zwrócenie tylko części wyników „Rok”, z pominięciem minut itp.

Where datepart(year, SubmitDate) = '2017'

0
select *, cast ([col1] as date) <name of the column> from test where date = 'mm/dd/yyyy'

„col1” to nazwa kolumny z datą i godziną
<nazwa kolumny> tutaj możesz zmienić nazwę według potrzeb


0
select *
  from invoice
 where TRUNC(created_date) <=TRUNC(to_date('04-MAR-18 15:00:00','dd-mon-yy hh24:mi:ss'));

0

Występuje problem z datami i językami, a sposobem na uniknięcie tego jest pytanie o daty w tym formacie RRRRMMDD.

Ten sposób poniżej powinien być najszybszy zgodnie z poniższym linkiem. Sprawdziłem w SQL Server 2012 i zgadzam się z linkiem.

select * from test where date >= '20141903' AND date < DATEADD(DAY, 1, '20141903');

0

Użyj tego

select * from TableName where DateTimeField > date() and  DateTimeField < date() + 1

-1

Przetestuj to zapytanie.

SELECT *,DATE(chat_reg_date) AS is_date,TIME(chat_reg_time) AS is_time FROM chat WHERE chat_inbox_key='$chat_key' 
                         ORDER BY is_date DESC, is_time DESC

-1
select * from invoice where TRANS_DATE_D>= to_date  ('20170831115959','YYYYMMDDHH24MISS')
and TRANS_DATE_D<= to_date  ('20171031115959','YYYYMMDDHH24MISS');

Myślę, że to jest składnia Oracle, nie działa na serwerze sql
ceinmart

-2
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018'  and  DATEPART(day,[TIMESTAMP]) = '16' and  DATEPART(month,[TIMESTAMP]) = '11'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.