Frage

Ich habe ein varchar Feld in SQL Server 2005 bekam, die einen Zeitwert im Format "hh: mm" ist zu speichern. Ss.mmmm“

mit dem eingebauten in Aggregatfunktion dieser Zeitwerte

Was will ich wirklich tun, ist die durchschnittliche nehmen. Dies ist jedoch:

SELECT AVG(TimeField) FROM TableWithTimeValues

funktioniert nicht, da (natürlich) SQL wird nicht durchschnittlich Varchars. Doch diese

SELECT AVG(CAST(TimeField as datetime)) FROM TableWithTimeValues

auch nicht funktionieren. So nahe, wie ich sagen kann, weiß nicht, wie SQL-Wert mit nur Zeit und kein Datum in ein Datetime-Feld zu konvertieren. Ich habe eine Vielzahl von Dingen versucht, SQL zu erhalten, das Feld in ein Datetime zu drehen, aber so weit, kein Glück.

Kann mir jemand einen besseren Weg vorschlagen?

War es hilfreich?

Lösung

SQL Server kann einen zeitlich nur Teil eines Datetime-Wert von Zeichenfolge in Datetime, aber in Ihrem Beispiel konvertieren, haben Sie eine Genauigkeit von 4 Dezimalstellen. SQL Server 2005 erkennt nur 3 Plätze. Daher müssen Sie das rechte Zeichen kürzen:

create table #TableWithTimeValues
(
    TimeField varchar(13) not null
)

insert into #TableWithTimeValues
select '04:00:00.0000'
union all
select '05:00:00.0000'
union all
select '06:00:00.0000'

SELECT CAST(TimeField as datetime) FROM #TableWithTimeValues
--Msg 241, Level 16, State 1, Line 1
--Conversion failed when converting datetime from character string.

SELECT CAST(LEFT(TimeField, 12) as datetime) FROM #TableWithTimeValues
--Success!

Dies wird gültige Werte in eine DATETIME- auf 1900-01-01 Start konvertieren. SQL Server berechnet Daten basierend auf 1 Tag = 1 (integer). Portionen von Tagen werden dann Teile des Wertes 1 (d.h. mittags beträgt 0,5). Da ein Datum nicht in der Umwandlung angegeben wurde, SQL Server den Wert von 0 Tage (1900-01-01) zugeordnet, die Platz für unseren Bedarf den Zeitanteil mitteln.

AVG Vorgang müssen auf einem DATETIME-, müssen Sie zuerst die DATETIME- in einen Dezimalwert konvertieren, führen Sie die Aggregation, dann zurück geworfen. Zum Beispiel

SELECT CAST(AVG(CAST(CAST(LEFT(TimeField, 12) as datetime) AS FLOAT)) AS DATETIME) FROM #TableWithTimeValues
--1900-01-01 05:00:00.000

Wenn Sie dies mit einer zusätzlichen Dezimalstelle speichern müssen, können Sie die DATETIME- zu einem VARCHAR mit Zeitabschnitt konvertieren nur und Pad zu 13 Zeichen die Zeichenfolge zurück:

SELECT CONVERT(VARCHAR, CAST(AVG(CAST(CAST(LEFT(TimeField, 12) as datetime) AS FLOAT)) AS DATETIME), 114) + '0' FROM #TableWithTimeValues

Andere Tipps

Versuchen Sie, diese

AVG(CAST(CAST('1900-01-01 ' + TimeField AS DateTime) AS Float))

Sie sollten wirklich auf jeden Fall diejenigen, die in einem Datetime-Spalte speichern. Verwenden Sie einfach ein einheitliches Datum für den Teil (1.1.1900 ist sehr häufig). Dann können Sie einfach anrufen AVG () und nicht darum kümmern.

habe ich Cadaeic Antwort eine Antwort zu bekommen ich suchte, so dass ich dachte, ich sollte den Code teilen ....

Ich war auf der Suche nach einer Abfrage, die zusammen all meine Zeiten im Durchschnitt würde und geben Sie mir eine Gesamtdurchlaufzeit für alle Zulassungen. Im Folgenden finden Sie eine verschachtelte Anweisung, dass Sie die AVG TAT für einzelne IDs und und wenn verschachtelt eine Gesamt TAT

gibt
SELECT 
-- calculates overall TAT for ALL Approvals for specified period of time
-- depending on parameters of query
CONVERT(VARCHAR, CAST(AVG(CAST(CAST(LEFT(Tat_mins, 12) as datetime) AS FLOAT)) AS DATETIME), 108) + '0'

from 
(
-- tat is for individual approvals 
SELECT 
dbo.credit_application.decision_status,
dbo.credit_application.application_id,
cast(dbo.credit_application.data_entry_complete as date) as'Data Entry Date',
cast(dbo.credit_application.decision_date as DATE) as 'Decision Date',
avg(datediff(minute, dbo.credit_application.data_entry_complete, dbo.credit_application.decision_date)) as 'TAT Minutes',
convert (char(5), DateAdd(minute, Datediff(minute,dbo.credit_application.data_entry_complete, dbo.credit_application.decision_date),'00:00:00'),108) as 'TAT_Mins'
FROM  dbo.credit_application
where Decision_status not in ('P','N')

group by dbo.credit_application.decision_status,
dbo.credit_application.data_entry_complete,
dbo.credit_application.decision_date
--dbo.credit_application.application_id
)bb

Wie denken Sie über Datetime Durchschnitt?

Ich denke, dass Sie durch einige Zeit (Stunde?) Und Anzeige Count (*)?

GRUPPE brauchen

SQL Server speichert Datumsdaten als 2 4-Byte-Integer, daher nehmen ein Datetime 8 Byte. Die erste ist, Tage seit dem Basisdatum und der zweite ist Millisekunden seit Mitternacht.

Sie können einen Datetime-Wert in eine ganze Zahl konvertieren und mathematische Operationen durchführen, aber die Konvertiten nur gibt die „Tage“ Teil des Datetime-Wert z.B. select convert (int, getdate ()). Schwieriger ist es, die „Zeit“ Teil als Integer zurück.

Ist die Verwendung von SQL Server 2008 eine Option für Sie? Diese Version hat eine neuen dedizierten Zeitdatentyp .

Danke, Andy.

Ich würde den Unterschied zwischen all den Terminen arbeiten und einem beliebigen Punkt (01/01/1900), dem Durchschnitt und es dann auf den beliebigen Punkt hinzufügen zurück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top