Datediff بين غير متتالية الصفوف في الجدول
-
19-09-2019 - |
سؤال
وأود أن أغتنم متوسط الفارق الزمني من جدول1 أدناه.القيم ليست متتالية و في بعض الأحيان قيمة الوقت تتكرر, لذلك أنا بحاجة إلى 1) فرز حسب الوقت ، 2) تجاهل غير القيم الفريدة ، 3) أداء الفرق في الوقت (بالملي ثانية) ثم 4) متوسط الناتج فارق التوقيت القيم.كذلك أود 5) الحد datediff عملية اختيار الوقت مثل حيث _TimeStamp >= '20091220 11:59:56.1' و _TimeStamp <= _TimeStamp >= '20091220 11:59:56.8'.أنا جميلة الحيرة في كيفية وضع كل هذا معا!
جدول1:
_TimeStamp
2009-12-20 11:59:56.0
2009-12-20 11:59:56.5
2009-12-20 11:59:56.3
2009-12-20 11:59:56.4
2009-12-20 11:59:56.4
2009-12-20 11:59:56.9
المحلول
هنا واحد أن يعمل و ليست قبيحة:
;WITH Time_CTE AS
(
SELECT
MIN(_Timestamp) AS dt,
ROW_NUMBER() OVER (ORDER BY MIN(_Timestamp)) AS RowNum
FROM Table1
GROUP BY _Timestamp
)
SELECT
t1.dt AS StartDate,
t2.dt AS EndDate,
DATEDIFF(MS, t1.dt, t2.dt) AS Elapsed
FROM Time_CTE t1
INNER JOIN Time_CTE t2
ON t2.RowNum = t1.RowNum + 1
سوف تعطيك الناتج التالي من المثال الخاص بك:
StartDate | EndDate | Elapsed
------------------------+-------------------------+--------
2009-12-20 11:59:56.000 | 2009-12-20 11:59:56.300 | 300
2009-12-20 11:59:56.300 | 2009-12-20 11:59:56.400 | 100
2009-12-20 11:59:56.400 | 2009-12-20 11:59:56.500 | 100
2009-12-20 11:59:56.500 | 2009-12-20 11:59:56.900 | 400
تحرير:إذا كنت ترغب في تقييد وقت يتراوح ثم فقط إضافة WHERE _Timestamp BETWEEN @StartDate AND @EndDate
قبل GROUP BY
خط.
Edit2:وإذا كنت تريد المتوسط ، ثم تغيير النهائي SELECT t1.dt, ...
بيان:
SELECT AVG(DATEDIFF(MS, t1.dt, t2.dt))
FROM Time_CTE t1 ... (same as above)
نصائح أخرى
الخطوة 1 اختيار فريدة من نوعها فقط مرات:
SELECT DISTINCT _TimeStamp FROM table
WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8';
ثم, إذا كنت تريد أن, يقول, قارن جميع الأوقات مع بعضها البعض (غير متأكد من كيفية كنت ترغب في تحديد مرات), هل يمكن فعل شيء مجنون مثل:
SELECT t1._TimeStamp, t2._TimeStamp, DATEDIFF(ms,t1._TimeStamp,t2._TimeStamp) FROM
(SELECT DISTINCT _TimeStamp FROM table
WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t1
INNER JOIN
(SELECT DISTINCT _TimeStamp FROM table
WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t2
WHERE t1._TimeStamp != t2._TimeStamp;
فلسفتي قد يكون خارج لأنني قادم من الخلية ، ولكن شيئا من هذا القبيل يجب أن تعمل.
إذا كنت تريد المتوسط ، قد تتمكن من محاولة أخذ المتوسط من النتائج المذكورة أعلاه:
SELECT AVG(DATEDIFF(ms,t1._TimeStamp,t2._TimeStamp)) FROM
(SELECT DISTINCT _TimeStamp FROM table
WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t1
INNER JOIN
(SELECT DISTINCT _TimeStamp FROM table
WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t2
WHERE t1._TimeStamp != t2._TimeStamp;
لا تزال تختبر ، ولكن من الناحية النظرية ، أعتقد أنه يجب أن تعمل.
إذا الافتراضات على ما تريد صحيحة ، ثم أرى طريقتين للقيام بذلك.
الطريقة المباشرة:
SELECT
AVG(DATEDIFF(ms, T1.my_time, T2.my_time))
FROM
My_Table T1
INNER JOIN My_Table T2 ON
T2.my_time > T1.my_time
WHERE
NOT EXISTS
(
SELECT
*
FROM
My_Table T3
WHERE
(T3.my_time > T1.my_time AND T3.my_time < T2.my_time) OR
(T3.my_time = T1.my_time AND T3.my_pk < T1.my_pk) OR
(T3.my_time = T2.my_time AND T3.my_pk < T2.my_pk)
)
صعبة الطريقة:
SELECT
DATEDIFF(ms, MIN(my_time), MAX(my_time))/(COUNT(DISTINCT my_time) - 1)
FROM
My_Table
بعد كل شيء, متوسط الاختلافات هي فقط مجموع الفرق مقسوما على عدد الانقسامات التي كنت كسر.
سوف تحتاج إلى إضافة العبارات عن نطاق التاريخ إذا كنت تريد أن تحد من ذلك وسوف تحتاج إلى حساب إمكانية القسمة على صفر في الاستعلام الثاني.