如何根据如下记录删除一条记录
How to delete a record depending on the following record
我有一个 table 包含以下列
Car | User | Location | Time | Type
类型可以是
'OUT' if the user's request to rent the car is accepted
'IN' when the user stops using the car and registers it back into the system
'DENIED' when the access to rent the car is denied
所以关于类型的记录顺序应该是OUT-IN(时间升序)
存在不一致的数据,其中可能有几行具有相同的汽车、用户、位置和类型值,如下所示
Car | User | Location | Time | Type
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 03:12:45 | OUT //should be deleted
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 04:12:45 | OUT //should be deleted
-----------------------------------------------------------------
2 | Sam | New York | 2022-02-12 04:42:45 | OUT
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 04:50:00 | OUT //should be kept
-----------------------------------------------------------------
1 | Sam | New York | 2022-02-12 07:32:12 | IN
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 08:18:45 | IN //should be deleted
-----------------------------------------------------------------
3 | Mia | San Franc | 2022-02-12 09:12:43 | OUT
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 09:27:23 | IN //should be kept
因此只应保留最后的 OUT 和 IN 记录,而应删除其他重复记录。
为了更容易获得帮助
CREATE TABLE rent_logs (
car varchar(30),
user varchar(30),
location varchar(30),
time datetime
type varchar(10)
);
INSERT INTO rent_logs ( car, username, location, time, type ) VALUES
( 1, 'Ben', 'Chicago','2022-02-12 03:12:45', 'OUT' ), ( 1, 'Ben', 'Chicago',' 2022-02-12 04:12:45 ', 'OUT' ), ( 2, 'Sam', 'New york','2022-02-12 04:42:45', 'OUT' ), ( 1, 'Ben', 'Chicago','2022-02-12 04:50:00', 'OUT' ), ( 2, 'Sam', 'New york','2022-02-12 07:32:12 ', 'IN' ), ( 1, 'Ben', 'Chicago','22022-02-12 08:18:45', 'IN' ), ( 3, 'Mia', 'Chicago','2022-02-12 09:12:43', 'OUT' ), ( 1, 'Ben', 'Chicago','2022-02-12 09:27:23', 'IN' )
您可以在 Type
字段上使用一对 window 函数:
这些window函数将根据涉及以下字段的特定分区按此顺序应用:User
、Car
、Location
.
获得这些值后,您可以在字段 Type
满足以下条件之一时检索行:
Type = OUT
和 TypeNext = IN
(最后 OUT
)
Type = IN
和 TypePrev = IN
而不是 TypeNext = IN
(最后 IN
)
Type = DENIED
如果你在近行有更复杂的条件,你可以通过这三个计算值来处理它们。
WITH cte AS (
SELECT Car,
User,
Location,
Time,
LAG(Type) OVER(
PARTITION BY User, Car, Location
ORDER BY Time) AS TypePrev,
Type,
LEAD(Type) OVER(
PARTITION BY User, Car, Location
ORDER BY Time) AS TypeNext
FROM rent_logs
)
SELECT Car,
User,
Location,
Time,
Type
FROM cte
WHERE (Type = 'OUT' AND TypeNext = 'IN')
OR (Type = 'IN' AND TypePrev = 'IN' AND (TypeNext = 'OUT' OR TypeNext IS NULL))
OR (TypePrev IS NULL AND TypeNext IS NULL)
OR (Type = 'DENIED')
ORDER BY User,
Time
勾选 SQL Fiddle here.
如果您想稍微了解一下它是如何工作的以及 fiddle link 中的中间结果,我建议您从评论行中删除评论并评论条件在 WHERE
子句中。
我有一个 table 包含以下列
Car | User | Location | Time | Type
类型可以是
'OUT' if the user's request to rent the car is accepted
'IN' when the user stops using the car and registers it back into the system
'DENIED' when the access to rent the car is denied
所以关于类型的记录顺序应该是OUT-IN(时间升序)
存在不一致的数据,其中可能有几行具有相同的汽车、用户、位置和类型值,如下所示
Car | User | Location | Time | Type
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 03:12:45 | OUT //should be deleted
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 04:12:45 | OUT //should be deleted
-----------------------------------------------------------------
2 | Sam | New York | 2022-02-12 04:42:45 | OUT
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 04:50:00 | OUT //should be kept
-----------------------------------------------------------------
1 | Sam | New York | 2022-02-12 07:32:12 | IN
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 08:18:45 | IN //should be deleted
-----------------------------------------------------------------
3 | Mia | San Franc | 2022-02-12 09:12:43 | OUT
-----------------------------------------------------------------
1 | Ben | Chicago | 2022-02-12 09:27:23 | IN //should be kept
因此只应保留最后的 OUT 和 IN 记录,而应删除其他重复记录。
为了更容易获得帮助
CREATE TABLE rent_logs (
car varchar(30),
user varchar(30),
location varchar(30),
time datetime
type varchar(10)
);
INSERT INTO rent_logs ( car, username, location, time, type ) VALUES
( 1, 'Ben', 'Chicago','2022-02-12 03:12:45', 'OUT' ), ( 1, 'Ben', 'Chicago',' 2022-02-12 04:12:45 ', 'OUT' ), ( 2, 'Sam', 'New york','2022-02-12 04:42:45', 'OUT' ), ( 1, 'Ben', 'Chicago','2022-02-12 04:50:00', 'OUT' ), ( 2, 'Sam', 'New york','2022-02-12 07:32:12 ', 'IN' ), ( 1, 'Ben', 'Chicago','22022-02-12 08:18:45', 'IN' ), ( 3, 'Mia', 'Chicago','2022-02-12 09:12:43', 'OUT' ), ( 1, 'Ben', 'Chicago','2022-02-12 09:27:23', 'IN' )
您可以在 Type
字段上使用一对 window 函数:
这些window函数将根据涉及以下字段的特定分区按此顺序应用:User
、Car
、Location
.
获得这些值后,您可以在字段 Type
满足以下条件之一时检索行:
Type = OUT
和TypeNext = IN
(最后OUT
)Type = IN
和TypePrev = IN
而不是TypeNext = IN
(最后IN
)Type = DENIED
如果你在近行有更复杂的条件,你可以通过这三个计算值来处理它们。
WITH cte AS (
SELECT Car,
User,
Location,
Time,
LAG(Type) OVER(
PARTITION BY User, Car, Location
ORDER BY Time) AS TypePrev,
Type,
LEAD(Type) OVER(
PARTITION BY User, Car, Location
ORDER BY Time) AS TypeNext
FROM rent_logs
)
SELECT Car,
User,
Location,
Time,
Type
FROM cte
WHERE (Type = 'OUT' AND TypeNext = 'IN')
OR (Type = 'IN' AND TypePrev = 'IN' AND (TypeNext = 'OUT' OR TypeNext IS NULL))
OR (TypePrev IS NULL AND TypeNext IS NULL)
OR (Type = 'DENIED')
ORDER BY User,
Time
勾选 SQL Fiddle here.
如果您想稍微了解一下它是如何工作的以及 fiddle link 中的中间结果,我建议您从评论行中删除评论并评论条件在 WHERE
子句中。