[英]How to insert unique rows from one table to another table in postgres?
我想將 product_table 中唯一的行插入到 bill_table_unique 中。
然后必須將重復的行從 product_table 移動到 bill_table_duplicate。
一旦所有的數據都被移動意味着 product_table 條目必須被清除(只有移動的行必須被清除)
輸入:
產品表
id bill_id entry_date product_name stock
-------------------------------------------------------------------
1 009 2020-12-11 02:05:20.09876 apple 5
2 009 2020-12-11 02:05:20.09876 apple 5
3 009 2020-09-11 02:05:20.09876 apple 5
4 002 2020-12-11 02:05:20.09876 berry 5
5 002 2020-12-11 02:05:20.09876 berry 5
6 004 2020-12-11 10:05:20.09876 pineapple 1
7 006 2020-12-11 10:05:20.09876 pineapple 4
第 1步:將 product_table 中唯一的行插入到 bill_table_unique。
Output:bill_table_unique
id bill_id entry_date product_name stock
-------------------------------------------------------------------
1 009 2020-12-11 02:05:20.09876 apple 5
2 009 2020-09-11 02:05:20.09876 apple 5
3 002 2020-12-11 02:05:20.09876 berry 5
4 004 2020-12-11 10:05:20.09876 pineapple 1
5 006 2020-12-11 10:05:20.09876 pineapple 4
第 2步:然后必須將重復的行從 product_table 移動到 bill_table_duplicate。
Output:bill_table_duplicate
id bill_id entry_date product_name stock
---------------------------------------------------------------------
1 009 2020-12-11 02:05:20.09876 apple 5
2 002 2020-12-11 02:05:20.09876 berry 5
第 3 步:一旦所有數據都被移動意味着 product_table 條目必須被清除(只有移動的行必須被清除)
Output:product_table
id bill_id entry_date product_name stock
--------------------------------------------------------------------
使用如下兩個查詢:
Insert into bill_table_unique
Select distinct bill_id, entry_date, product_name, stock
From product_table;
Insert into bill_table_duplicate
Select bill_id, entry_date, product_name, stock
From
(Select bill_id, entry_date, product_name, stock,
Row_number() over (partirion by bill_id, entry_date, product_name, stock
order by null) as rn
From product_table) t
Where rn >= 2;
CREATE TABLE foo (id INTEGER PRIMARY KEY, bill_id TEXT NOT NULL,
entry_date TIMESTAMP NOT NULL, product_name TEXT NOT NULL,
stock INTEGER NOT NULL);
\copy foo from stdin
1 009 2020-12-11 02:05:20.09876 apple 5
2 009 2020-12-11 02:05:20.09876 apple 5
3 009 2020-09-11 02:05:20.09876 apple 5
4 002 2020-12-11 02:05:20.09876 berry 5
5 002 2020-12-11 02:05:20.09876 berry 5
6 004 2020-12-11 10:05:20.09876 pineapple 1
7 006 2020-12-11 10:05:20.09876 pineapple 4
\.
CREATE TABLE foo1 (id SERIAL PRIMARY KEY, bill_id TEXT NOT NULL,
entry_date TIMESTAMP NOT NULL, product_name TEXT NOT NULL,
stock INTEGER NOT NULL);
CREATE TABLE foo2 (id SERIAL PRIMARY KEY, bill_id TEXT NOT NULL,
entry_date TIMESTAMP NOT NULL, product_name TEXT NOT NULL,
stock INTEGER NOT NULL);
WITH a AS (
SELECT min(id) id, bill_id, entry_date, product_name, stock
FROM foo GROUP BY bill_id, entry_date, product_name, stock
), b AS (
INSERT INTO foo1 (bill_id, entry_date, product_name, stock)
SELECT bill_id, entry_date, product_name, stock FROM a)
INSERT INTO foo2 (bill_id, entry_date, product_name, stock)
SELECT f.bill_id, f.entry_date, f.product_name, f.stock
FROM foo f LEFT JOIN a USING (id) WHERE a.id IS NULL;
WITH 查詢中的第一個 CTE 計算要傳輸到表 foo1 中的行。 我選擇了具有最小 id 的行。
第二個 CTE 插入行。
第三個 CTE 插入上一步中沒有插入的行,這些是重復的。
如果行數不太大,這應該使用 hashaggregate 和 hashjoin,並且比使用排序的查詢快得多。 此外,重復數據刪除只進行一次。
第 3 步:一旦所有數據都已被移動意味着 product_table 條目必須被清除(只有移動的行必須被清除)
由於問題沒有指定不應該移動哪些行的條件,因此原始表中的所有行都已移動,因此:
TRUNCATE TABLE product_table;
我會使用row_number()
來枚舉原始表中的行。 然后插入其他表只依賴簡單的過濾器:
WITH pt AS (
SELECT pt.*,
ROW_NUMBER() OVER (PARTITION BY bill_id, entry_date, product_name, stock ORDER BY id) as seqnum
FROM product_table pt
),
btu AS (
INSERT INTO bill_table_unique (bill_id, entry_date, product_name, stock)
SELECT bill_id, entry_date, product_name, stock
FROM pt
WHERE seqnum = 1
)
INSERT INTO bill_table_duplicate (bill_id, entry_date, product_name, stock)
SELECT bill_id, entry_date, product_name, stock
FROM pt
WHERE seqnum > 1;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.