sql >> Database teknologi >  >> RDS >> Sqlserver

Konverter 'datetime offset' til 'time' i SQL Server (T-SQL-eksempler)

Hvis du har en datetime offset værdi, men du behøver ikke dato- og tidszoneforskydningsdelen, der konverterer den til tid vil spare dig for en masse lagerplads (mens du fjerner unødvendige detaljer fra værdien). Denne artikel indeholder eksempler på konvertering af en datotidsforskydning værdi til en tid værdi i SQL Server.

datetime offset datatypen inkluderer dato og klokkeslæt med en tidszoneforskydning. Den har også en brøksekundersdel mellem 0 og 7 (dette afhænger af, hvor mange brøksekunder der er tildelt den). Dette gøres ved at bruge datetimeoffset(n) syntaks. Hvis du ikke angiver dette, vil det bruge 7 (standard). Denne datatypes lagerstørrelse er enten 8, 9 eller 10 bytes, afhængigt af den anvendte præcision. Dens nøjagtighed er 100 nanosekunder.

tidspunktet datatype på den anden side, inkluderer kun tiden. Det inkluderer ikke datoen, og det inkluderer ikke tidszoneforskydningen. Dog i lighed med datetime offset det giver dig også mulighed for at angive en delsekunder mellem 0 og 7 (ved at bruge time(n) syntaks). Den bruger enten 3, 4 eller 5 bytes, afhængig af præcisionen.

Når du konverterer en datotidsforskydning værdi til en tid datatype, mister du datodelen. Du mister også tidszoneforskydningen. Du reducerer dog også lagerstørrelsen fra mellem 8 og 10 bytes ned til enten 3, 4 eller 5 bytes. Du vil dog kun foretage denne konvertering, hvis du ikke har brug for datodelen eller tidszoneforskydningen.

Bemærk, at lagerbeløbene, der er angivet her, er de beløb, der er angivet i Microsoft-dokumentationen. Disse datatyper bruger dog også 1 byte til at gemme præcisionen. Derfor skal du tilføje 1 byte til de beløb, der er angivet her.

Eksempel 1 – Implicit konvertering

Her er et eksempel på en implicit konvertering mellem datetime offset og tid .

DECLARE 
  @thedatetimeoffset datetimeoffset, 
  @thetime time;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultat:

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

Dette er en implicit konvertering, fordi vi ikke bruger en konverteringsfunktion (som dem nedenfor) til eksplicit at konvertere den. I dette tilfælde udfører SQL Server en implicit konvertering bag kulisserne, når vi forsøger at tildele datetime offset værdi til en tid variabel.

Her kan vi se, at tiden værdien inkluderer kun klokkeslættet (uden datokomponenten). Komponenterne for dato- og tidszoneforskydning er blevet fjernet fra værdien.

I dette eksempel bruger begge datatyper standardpræcisionen (hvilket resulterer i 7 decimaler). Dette resulterer i datetime offset værdi ved hjælp af 10 bytes og tiden værdi ved brug af 5 bytes.

Eksempel 2 – Præcision

Det nøjagtige resultat vil afhænge af præcisionsindstillingerne for hver datatype. I det næste eksempel er tiden værdi bruger en lavere præcision i forhold til den oprindelige dato-tidsforskydning værdi:

DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultat:

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1230000 |
+------------------------------------+------------------+

Mit system viser efterfølgende nuller, men pointen er, at tiden værdi har nu en præcision på kun 3 decimaler sammenlignet med de 7 decimaler, som den oprindelige værdi bruger.

Reduktion af præcisionen kan også resultere i tiden værdi rundes op. Her er et eksempel:

DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1235555 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultat:

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1240000 |
+------------------------------------+------------------+

I dette tilfælde ender vi med en brøkdel af 124 i stedet for 123 , fordi det følgende ciffer var 5 eller højere.

Eksempel 3 – Eksplicit konvertering ved hjælp af CAST()

Her er et eksempel på en eksplicit konvertering. I dette tilfælde bruger jeg CAST() funktion direkte i SELECT sætning til eksplicit at konvertere mellem datetimeoffset og tid .

DECLARE @thedatetimeoffset datetimeoffset;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  CAST(@thedatetimeoffset AS time) AS 'time'; 

Resultat:

+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

Eksempel 4 – Eksplicit konvertering ved hjælp af CONVERT()

Her er et eksempel på en eksplicit konvertering ved hjælp af CONVERT() funktion i stedet for CAST() .

DECLARE @thedatetimeoffset datetimeoffset;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  CONVERT(time, @thedatetimeoffset) AS 'time'; 

Resultat:

+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

  1. Hvorfor er usigneret heltal ikke tilgængelig i PostgreSQL?

  2. Ret "FEJL:hver INTERSECT-forespørgsel skal have det samme antal kolonner" i PostgreSQL

  3. Rekursive kategorier med en enkelt forespørgsel?

  4. Hvordan COT() virker i MariaDB