假設我有一個這樣的 SQL 表:
| 序列號(pk) | 名稱 | 地位 | 地點 | 時間更新 |
|---|---|---|---|---|
| 1 | '喬' | '在家' | '美國' | 01:30 |
| 2 | '簡' | 'at_store' | '美國' | 02:30 |
| 3 | '喬' | '駕駛' | '美國' | 12:15 |
| 4 | '喬' | '駕駛' | '美國' | 13:30 |
| 5 | '喬' | 'at_store' | '美國' | 15:00 |
| 5 | '喬' | 'at_store' | '美國' | 15:15 |
| 6 | '喬' | '駕駛' | '美國' | 16:00 |
| 7 | '喬' | '駕駛' | '美國' | 17:10 |
| 8 | '喬' | '在家' | '美國' | 20:00 |
在這個表中可以有三種不同的狀態:“at_home”、“at_store”和“driving”。
我想要一個按時間順序排列的每個人的動作。例如,對于 joe,這看起來像 at_home ->driving ->driving -> at_store -> at_store ->driving ->driving -> at_home
但是,我想洗掉任何重復的“駕駛”狀態,只保留最早的。例如,對于 joe,這看起來像 at_home ->driving -> at_store -> at_store ->driving -> at_home。我不想洗掉重復的“at_home”或“at_store”
在這個例子中,我想從 12:15 開始保持“駕駛”狀態,并在 16:00 保持“駕駛”狀態,同時洗掉后面的重復狀態。
我想專門為每個人執行此操作,因此當我執行“按 time_updated 訂購”時,我可以按順序查看該人的所有條目。
如果我使用 查詢結果表"select * from db where name = 'joe' order by time_updated",我的理想結果是:
| 序列號(pk) | 名稱 | 地位 | 地點 | 時間更新 |
|---|---|---|---|---|
| 1 | '喬' | '在家' | '美國' | 01:30 |
| 3 | '喬' | '駕駛' | '美國' | 12:15 |
| 5 | '喬' | 'at_store' | '美國' | 15:00 |
| 5 | '喬' | 'at_store' | '美國' | 15:15 |
| 6 | '喬' | '駕駛' | '美國' | 16:00 |
| 8 | '喬' | '在家' | '美國' | 20:00 |
有沒有辦法在 postgres 中做到這一點?
謝謝
uj5u.com熱心網友回復:
您可以使用具有存在邏輯的洗掉:
DELETE
FROM yourTable t1
WHERE status = 'driving' AND
NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.name = t1.name AND
t2.time_updated < t1.time_updated);
uj5u.com熱心網友回復:
首先,您獲取結果并按日期以相反的順序對它們進行排序以獲得最后一行,您甚至可以將此搜索限制為其中幾個或僅最后一個。
SELECT * FROM table ORDER BY time_updated DESC LIMIT 1;
那么如果狀態是“正在開車”
UPDATE table SET time_updated = currenttime WHERE id = currentID
您可以直接在 postgres 上使用觸發器和程序自動執行此操作,但這超出了這個問題
uj5u.com熱心網友回復:
您不需要洗掉帶有status= 'driving' (by name) 的連續行,您可以使用此查詢 (使用window function LAG())從結果中排除它們:
WITH sq AS (SELECT *,
CASE WHEN status = 'driving' AND status = LAG(status) OVER (PARTITION BY name ORDER BY time_updated) THEN 1 ELSE 0 END contiguous_driving
FROM t)
SELECT *
FROM sq
WHERE name = 'joe' AND contiguous_driving = 0
ORDER BY time_updated;
如果您仍想洗掉它們,可以使用相同的子查詢:
WITH sq AS (SELECT *,
CASE WHEN status = 'driving' AND status = LAG(status) OVER (PARTITION BY name ORDER BY time_updated) THEN 1 ELSE 0 END contiguous_driving
FROM t)
DELETE FROM t
WHERE serial IN (SELECT serial
FROM sq
WHERE contiguous_driving = 1);
如果serialcolumn 是主鍵,則它不能有重復的值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/399478.html
標籤:sql PostgreSQL的
上一篇:選擇不包含任何負值或缺失值的行
