我有一个包含产品评论的Oracle数据库表。其中一列是sort_order
- 即从数据库读入Web前端时显示评论的顺序。
我需要从临时加载表(已经从CSV填充)批量插入一堆新评论到主评论表中。我的SQL是这样的:
INSERT INTO reviews
(product_code, sort_order, review_date, review_text)
(SELECT product_code, 10, review_date, review_text
FROM review_load_table)
;
但是,当然这不正确 - 只需在10
列中插入sort_order
即可获得每次新评价。
那么,如果我希望插入sort_order
字段的值比相应产品的最大现有值大1,我该怎么办呢?
答案 0 :(得分:2)
INSERT INTO reviews (product_code, sort_order, review_date, review_text)
SELECT rlt.product_code, COALESCE(1 + rp.maxso, 1),
rlt.review_date, rlt.review_text
FROM review_load_table rlt LEFT JOIN
(SELECT r.product_code, MAX(sort_order) as maxso
FROM reviews r
GROUP BY r.product_code
) rp
ON rlt.product_code = r.product_code;
如果您可以在临时表中多次出现产品并且想要不同的数字,请使用row_number()
:
INSERT INTO reviews (product_code, sort_order, review_date, review_text)
SELECT rlt.product_code,
COALESCE(rp.maxso, 0) + row_number() over (partition by rlt.product_code order by product_code),
rlt.review_date, rlt.review_text
FROM review_load_table rlt LEFT JOIN
(SELECT r.product_code, MAX(sort_order) as maxso
FROM reviews r
GROUP BY r.product_code
) rp
ON rlt.product_code = r.product_code
答案 1 :(得分:0)
您考虑使用序列吗?它将提供独特性,每一个新的价值都会比前一个更大(但是,它不会无间隙,但是 - 在我看来 - 你不应该担心这个)。
这是documentation所说的;看看,如果你有兴趣的话。
以下是演示:我创建了一个序列和两个表(review和review_load_table):
SQL> create sequence seq_sort;
Sequence created.
SQL> create table reviews
2 (product_code number,
3 sort_order number,
4 review_text varchar2(20));
Table created.
SQL> insert into reviews
2 select 100, seq_sort.nextval, 'Text 1' from dual;
1 row created.
SQL> create table review_load_table
2 (product_code number,
3 review_text varchar2(20));
Table created.
SQL> -- this insert simulates data loaded from the CSV file
SQL> insert into review_load_table
2 select 100, 'Text 2' from dual union
3 select 200, 'Text 3' from dual;
2 rows created.
SQL>
现在,让我们从临时表中复制数据:
SQL> insert into reviews
2 (product_code, sort_order, review_text)
3 (select product_code, seq_sort.nextval, review_text
4 from review_load_table
5 );
2 rows created.
SQL> select * from reviews order by product_code, sort_order;
PRODUCT_CODE SORT_ORDER REVIEW_TEXT
------------ ---------- --------------------
100 1 Text 1
100 2 Text 2
200 3 Text 3
SQL>
如您所见,SORT_ORDER值已正确设置。
如果您需要在插入期间对行进行预排序(例如,通过时间戳或其他任何列),您可以使用首先排序的子查询,然后将SEQ_SORT.NEXTVAL应用于它:
insert into reviews
(product_code, sort_order, review_text)
(select product_code, seq_sort.nextval, review_text
from (select product_code, review_text
from review_load_table
order by review_text desc
));