sql - 我如何循环插入查询?
问题描述
我有一个这样的问题:我需要优化应用程序,用db(postgreSQL),表是这样的:
CREATE TABLE voter_count(
id SERIAL,
name VARCHAR NOT NULL,
birthDate DATE NOT NULL,
count INT NOT NULL,
PRIMARY KEY(id),
UNIQUE (name, birthDate))
我有一千多个这样的选民,我需要将他们全部放入数据库,但其中有几个副本可以投票多次(从 2 到无穷大),当遇到这样的副本时,我需要,增加现有的计数字段(对于具有相同姓名和出生日期的选民)。之前我只是检查了表中是否有这样的选民,如果有,然后找到它并增加计数。
但是程序运行时间太长了,我尝试通过 MULTI INSERT 来完成,并使用 ON CONFLICT DO UPDATE 来增加计数,但是我得到一个错误,然后我在 stackoverflow 上问了一个问题,并且有人提议我做很多通过循环插入,但在 PostgreSQL 中。
INSERT INTO voter_count(name, birthdate, count)
VALUES
('Ivan', '1998-08-05', 1),
('Sergey', '1998-08-29', 1),
('Ivan', '1998-08-05', 1)
ON CONFLICT (name, birthdate) DO UPDATE SET count = (voter_count.count + 1)
问题:如何通过 PostgreSQL 循环插入。
解决方案
可能最好的选择是在没有主键的表中的所有数据之前插入,例如:
CREATE TABLE voter_count_with_duplicates(
name VARCHAR NOT NULL,
birthDate DATE NOT NULL)
然后用一条语句插入数据:
INSERT INTO voter_count (name, birthDate, count)
SELECT name, birthDate, COUNT(*)
FROM voter_count_with_duplicates
GROUP BY name, birthDate
请注意,如果您有结构化文本文件(例如 CSV 文件)中的数据,则可以voter_count_with_duplicates
使用单个COPY
语句将所有数据插入其中。
如果您必须在已填充表的情况下插入(大量)新数据,则有几种可能性。一种是使用评论中的解决方案。另一种是执行更新和插入:
WITH present_tuples AS
(SELECT name, birthDate, COUNT(*) AS num_of_new_votes
FROM voter_count_with_duplicates d JOIN voter_count c ON
v.name = d.name and v.birthDate = d.birthDate
GROUP BY name, birthDate)
UPDATE voter_count SET count = count + num_of_new_votes
FROM present_tuples
WHERE present_tuples.name = voter_count.name
AND present_tuples.birthDate = voter_count.birthDate;
WITH new_tuples AS
(SELECT name, birthDate, COUNT(*) AS votes
FROM voter_count_with_duplicates d
WHERE NOT EXISTS SELECT *
FROM voter_count c
WHERE v.name = d.name and v.birthDate = d.birthDate
GROUP BY name, birthDate)
INSERT INTO voter_count (name, birthDate, count)
SELECT name, birthDate, votes
FROM new_tuples;
推荐阅读
- ios - 如何在用户点击 SwiftUI 中的列表行时显示警报
- angular - 强制订阅者从服务重新请求数据?
- javascript - 使用 Angular 8 中的 put 调用更新本地 JSON 文件的单个属性
- c# - 格式化 Datagridview 对象中的日期时间列的问题
- reactjs - 可加载组件 SSR - 服务器统计文件中的块名称与客户端统计文件不同
- kubernetes - 如何在 K8S 作业上禁用 istio
- java - 使用 List 的方法中的“意外返回值”
- struct - 常见的 Lisp 处理结构槽顺序
- c++ - 条件不变的 if 语句会减慢我的 C++ 代码吗?
- python - 从雅虎财经中抓取数据