Confronta DATETIME e DATE ignorando la porzione di tempo


151

Ho due tabelle in cui la colonna [date]è di tipo DATETIME2(0).

Devo confrontare due record solo con le loro parti Data (giorno + mese + anno), scartando Parti tempo (ore + minuti + secondi).

Come lo posso fare?

Risposte:


252

Utilizzare il CASTnuovo DATEtipo di dati in SQL Server 2008 per confrontare solo la parte della data:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)

61

Un piccolo svantaggio nella risposta di Marc è che entrambi i campi della data sono stati tipizzati, il che significa che non sarai in grado di sfruttare alcun indice.

Pertanto, se è necessario scrivere una query che può beneficiare di un indice in un campo data, è necessario il seguente approccio (piuttosto contorto).

  • Il campo data indicizzato (chiamalo DF1) non deve essere toccato da alcun tipo di funzione.
  • Quindi devi confrontare DF1 con l'intera gamma di valori datetime per il giorno di DF2.
  • Cioè dalla data-parte di DF2, alla data-parte del giorno dopo DF2.
  • ie (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • NOTA : è molto importante che il confronto sia > = (uguaglianza consentita) alla data di DF2 e (rigorosamente) < il giorno dopo DF2. Inoltre, l'operatore TRA non funziona perché consente la parità su entrambi i lati.

PS: Un altro modo per estrarre solo la data (nelle versioni precedenti di SQL Server) è usare un trucco di come la data è rappresentata internamente.

  • Lanciare la data come un galleggiante.
  • Tronca la parte frazionaria
  • Trasmetti il ​​valore a un datetime
  • ie CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)

5

Anche se ho votato a favore la risposta contrassegnata come corretta. Volevo toccare alcune cose per chiunque inciampasse su questo.

In generale, se stai filtrando in modo specifico solo sui valori di Data . Microsoft consiglia di utilizzare il formato lingua neutra di ymdo y-m-d.

Si noti che il modulo "2007-02-12" è considerato indipendente dalla lingua solo per i tipi di dati DATE, DATETIME2 e DATETIMEOFFSET.

Fare un confronto delle date usando l'approccio sopra menzionato è semplice. Considera il seguente esempio inventato.

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    CONVERT(char(8), OrderDate, 112) = @filterDate

In un mondo perfetto, è necessario evitare qualsiasi manipolazione della colonna filtrata perché ciò può impedire a SQL Server di utilizzare gli indici in modo efficiente. Detto questo, se i dati che stai memorizzando riguardano solo la data e non l'ora, considera la memorizzazione come DATETIMEa mezzanotte come l'ora. Perché:

Quando SQL Server converte il valore letterale nel tipo di colonna filtrata, presuppone la mezzanotte quando non viene indicata una parte temporale. Se si desidera che un filtro di questo tipo restituisca tutte le righe dalla data specificata, è necessario assicurarsi di archiviare tutti i valori con mezzanotte come ora.

Quindi, supponendo che ti interessi solo della data e memorizzi i tuoi dati come tali. La query sopra può essere semplificata per:

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate

3

Puoi provare questo

CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')

Lo provo per MS SQL 2014 seguendo il codice

select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
            else '' end

-3

Per confrontare due date come MM / GG / AAAA con MM / GG / AAAA . Ricorda che per prima cosa il tipo di colonna del campo deve essere dateTime. Esempio: columnName: payment_date dataType: DateTime .

dopo puoi facilmente confrontarlo. La query è:

select  *  from demo_date where date >= '3/1/2015' and date <=  '3/31/2015'.

È molto semplice ...... Lo ha testato .....


Questo non risponde completamente alla domanda. Interroga per un mese, non un giorno.
Curtis Yallop,

Per la tua query di marzo: se la data è il 31/03/2015 alle 13:00, non verrà trovata. Dovresti usare <'4/1/2015'.
Curtis Yallop,

Considera anche l'utilizzo del formato data internazionale '2015-03-01'. In Canada (e in molti altri luoghi), un formato ufficiale è GG / MM / AAAA che rende ambigui e problematici entrambi i formati.
Curtis Yallop,

Questa risposta non riguarda 2 tabelle, come richiesto nella domanda.
Curtis Yallop,

Sì, sono d'accordo, ma sto solo provando una soluzione non una soluzione internazionale ... devi cambiare un po 'di ordine ...
pankaj
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.