2015-09-23 20 views
5

Có cách nào để lấy lại tất cả các bản ghi có số liệu thống kê chồng chéo dựa trên người dùng không?Tìm tất cả các hàng có ngày bắt đầu trước ngày kết thúc trước

Ví dụ;

TableA có các hàng sau;

TrainerID   StartTime   EndTime 
1234     10-1-2015 08:30  10-1-2015 09:00 
1234     10-1-2015 08:45  10-1-2015 09:15 
1234     10-1-2015 09:30  10-1-2015 10:00 
2345     10-1-2015 08:45  10-1-2015 09:15 
2345     10-1-2015 09:30  10-1-2015 10:00 

Tôi cần một truy vấn có thể kéo CHỈ kỷ lục sau đây vì nó là thời gian bắt đầu là trước khi thời gian kết thúc trước cho huấn luyện viên (double đã nhập):

1234     10-1-2015 08:45  10-1-2015 09:15 

Trả lời

2

Mã TỒN TẠI dưới đây sẽ cho bạn câu trả lời đó. Mã này đảm bảo rằng thời gian bắt đầu của mục nhập xung đột là trước khi bắt đầu mục nhập danh sách chính trong khi thời gian bắt đầu của xung đột vẫn còn sau thời gian bắt đầu của mục nhập danh sách thư.

SELECT * 
FROM tblTest clashing 
WHERE EXISTS 
(
    SELECT 1 
    FROM tblTest mainlist 
    WHERE clashing.trainderid = mainlist.trainderid 
     AND clashing.starttime < mainlist.endtime 
     AND clashing.starttime > mainlist.starttime 
) 

này cũng có thể được viết với một tuyên bố IN, nhưng tồn tại là nhiều hơn nữa hiệu quả

1

Để loại bỏ ngày trùng lặp bạn có thể sử dụng :

Demo

CREATE TABLE #TABLEA(TrainerID INT, StartDate DATETIME, EndDate DATETIME); 

INSERT INTO #TABLEA 
SELECT 1234, '10-1-2015 08:30', '10-1-2015 09:00' 
UNION ALL SELECT 1234 , '10-1-2015 08:45', '10-1-2015 09:15' 
UNION ALL SELECT 1234 , '10-1-2015 09:30', '10-1-2015 10:00' 
UNION ALL SELECT 2345 , '10-1-2015 08:45', '10-1-2015 09:15' 
UNION ALL SELECT 2345 , '10-1-2015 09:30', '10-1-2015 10:00'; 

SELECT 
    D.TrainerID, 
    [StartTime] = D.StartDate, 
    [EndTime] = (SELECT MIN(E.EndDate) 
       FROM #TABLEA E 
       WHERE E.EndDate >= D.EndDate 
       AND E.TrainerID = D.TrainerID 
       AND NOT EXISTS (SELECT 1 
           FROM #TABLEA E2 
           WHERE E.StartDate < E2.StartDate 
            AND E.EndDate > E2.StartDate 
            AND E.TrainerID = E2.TrainerID)) 
FROM #TABLEA D 
WHERE NOT EXISTS (SELECT 1 
        FROM #TABLEA D2 
        WHERE D.StartDate < D2.EndDate 
        AND D.EndDate > D2.EndDate 
        AND D.TrainerID = D2.TrainerID); 
1

Bạn có thể sử dụng mã bên dưới để nhận hàng yêu cầu, tuy nhiên dựa trên hàng logic của bạn từ id nhà huấn luyện tiếp theo (tức là 2345) cũng sẽ được đủ điều kiện

DECLARE @Trainers TABLE 
(
    TrainerId INT, 
    Start_Time datetime, 
    End_Time datetime 
) 
INSERT INTO @Trainers VALUES 
(1234,'10-1-2015 08:30','10-1-2015 09:00 '), 
(1234,'10-1-2015 08:45','10-1-2015 09:15'), 
(1234,'10-1-2015 09:30','10-1-2015 10:00'), 
(2345 ,' 10-1-2015 08:45','10-1-2015 09:15'), 
(2345 ,' 10-1-2015 09:30 ',' 10-1-2015 10:00') 


;WITH TrainersTemp AS 
     (
     SELECT *, ROW_NUMBER() OVER (ORDER BY trainerid) AS rn 
     FROM @Trainers 
     ) 
SELECT CX.TrainerId, CX.Start_Time, CX.End_Time 
FROM TrainersTemp CX JOIN TrainersTemp CY 
ON  CX.rn = CY.rn + 1 
WHERE CY.End_Time < CX.Start_Time 

Demo (SQL fiddle là xuống một lần nữa)

hoặc nếu bạn muốn xem tất cả các hàng ngoại trừ một lỗi sau đó sử dụng mã dưới đây

;WITH TrainersTempAll AS 
     (
     SELECT *, ROW_NUMBER() OVER (ORDER BY trainerid) AS rn 
     FROM @Trainers 
     ) 
SELECT CX.TrainerId, CX.Start_Time, CX.End_Time 
FROM TrainersTempAll CX JOIN TrainersTempAll CY 
ON  CX.rn = CY.rn + 1 
+0

Trainer "2345" không được tăng gấp đôi đặt mặc dù, vì vậy tôi không muốn kéo hàng đó. Đó là vấn đề của tôi; Tôi tiếp tục kéo TẤT CẢ hàng, khi tôi chỉ quan tâm nếu một huấn luyện viên được đặt gấp đôi vào một ngày nhất định. – akaWizzmaster

1

Trước hết bạn nên sắp xếp theo trainerId và Start_time. Và sau đó tham gia hai bảng với điều kiện chính xác.

Hãy thử truy vấn này:

;WITH TrainersTemp AS 
(
    SELECT *, ROW_NUMBER() OVER (ORDER BY trainerid, Start_Time) AS row_num 
    FROM Trainers 
) 
select t2.* from TrainersTemp t1 
join TrainersTemp t2 on t1.TrainerId = t2.TrainerId and t1.row_num = t2.row_num-1 
where t2.Start_Time<t1.End_Time 
1

Khi bạn sử dụng SQL Server 2012, bạn có thể sử dụng LAG chức năng, mà có thể sẽ hiệu quả hơn so với tự tham gia. Truy vấn trở nên khá đơn giản.

Đối với mỗi hàng LAG cung cấp cho bạn EndTime từ hàng trước đó (được phân đoạn bởi TrainerID). Sau đó, chỉ cần so sánh StartTime từ hàng hiện tại với EndTime từ hàng trước đó.

SQL Fiddle

WITH 
CTE 
AS 
(
    SELECT 
    TrainerID 
    ,StartTime 
    ,EndTime 
    ,LAG(EndTime) OVER(PARTITION BY TrainerID ORDER BY StartTime) AS PrevEndTime 
    FROM TableA 
) 
SELECT 
    TrainerID 
    ,StartTime 
    ,EndTime 
FROM CTE 
WHERE StartTime < PrevEndTime 
; 

Kết quả:

| TrainerID |     StartTime |     EndTime | 
|-----------|---------------------------|---------------------------| 
|  1234 | October, 01 2015 08:45:00 | October, 01 2015 09:15:00 | 
Các vấn đề liên quan