Hoş bir şekilde karmaşık bir soru, teşekkürler. Benim sorgu ile ilgilenir:
- Saatlerde kesin olarak ölçülemeyen dikkat edin. Hesaplamanın sonunda saniye sayısı toplam ve 3600'e bölünür. ya sonunda aylık sınırını kapsayan
- Yarışmaya (teşekkürler strawberry) başlamıştır geçerli ayda
- Yarışmaya (operasyonla bir giriş yoktur "1") ancak henüz bitmiş değil (hiçbir karşılık gelen operasyon "2 var ").
Ben test için aşağıdaki verileri kullanılmıştır:
INSERT INTO Attendance(UserId, Operation, CreatedDate) VALUES
(4, 1, '2016-01-01 15:00:00'),
(4, 2, '2016-01-01 19:00:00'),
(4, 1, '2016-01-31 23:00:00'),
(4, 2, '2016-02-01 01:00:00'),
(4, 1, '2016-02-20 23:18:59'),
(4, 2, '2016-02-20 23:19:50'),
(4, 1, '2016-02-20 23:20:28'),
(4, 2, '2016-02-20 23:20:31'),
(4, 1, '2016-02-29 23:00:00'),
(4, 2, '2016-03-01 01:00:00'),
(4, 1, '2016-03-02 15:00:00'),
(4, 2, '2016-03-02 18:00:00'),
(4, 1, '2016-03-22 10:00:00');
sorgu belirli bir ay boyunca tüm kullanıcıların saatlerini seçer. Bir sorguda bir aydan fazla bir süre için sonuçların seçilmesi, katılımcıların ay sınırlarını kapsadığı ve gerektiğinde aylar boyunca yinelemenin ve sorguyu tekrar tekrar çalıştırarak SQL'de uygun şekilde dört tarihin ayarlanması olasılığı nedeniyle daha karmaşıktır.
En içteki sorgu tüm varış zamanlarını ve tüm kullanıcılar için ilgili kalkış saatini seçer. Dış sorgu daha sonra onları mevcut ay ile kısıtlar, iki kez arasındaki farkı hesaplar ve bunları kullanıcı tarafından toplar.
SELECT UserId, SUM(TIMESTAMPDIFF(
SECOND,
GREATEST(TimeIn, '2016-02-01'),
LEAST(COALESCE(TimeOut, NOW()), '2016-03-01')))/3600 HoursInMonth
FROM (SELECT TimeIn.UserId, TimeIn.CreatedDate TimeIn, MIN(TimeOut.CreatedDate) TimeOut
FROM Attendance TimeIn
LEFT JOIN Attendance TimeOut ON TimeOut.UserId = TimeIn.UserId
AND TimeOut.Operation = 2
AND TimeOut.CreatedDate > TimeIn.CreatedDate
WHERE TimeIn.operation = 1
GROUP BY TimeIn.AttendanceId
ORDER BY TimeIn.CreatedDate) TimeInOut
WHERE DATE_FORMAT(TimeIn, '%Y-%m') = '2016-02'
OR DATE_FORMAT(TimeOut, '%Y-%m') = '2016-02'
OR (DATE_FORMAT(TimeIn, '%Y-%m') < '2016-02' AND TimeOut IS NULL)
GROUP BY UserId;
Bir çalışan 31'inci sırada denetler ve 1'i denetlerse ne olur? – Strawberry
@Strawberry Bu şeyi unuttum. Aynı fikir veya daha iyi bir şema önerir misiniz? –
Sadece soruya cevap verin. Ya da yapma. Sana kalmış. – Strawberry