如何插入 365 行并为每一行增加一天的日期
Posted
技术标签:
【中文标题】如何插入 365 行并为每一行增加一天的日期【英文标题】:How to insert 365 rows and increment date by one day for each row 【发布时间】:2021-05-10 07:58:07 【问题描述】:我有一张表,其架构如下:
date | from_city | to_city | rate_per_mile
我想为一对城市 (city1, city2, rate) 插入今天的汇率,并为从今天开始到接下来的 365 天的所有日期创建 365 行。
date | from_city | to_city | rate_per_mile
-------------------------------------------------------------
DATE(NOW()) | city1 | city2 | 13.23
DATE(NOW()) + 1 day | city1 | city2 | 13.23
DATE(NOW()) + 2 days | city1 | city2 | 13.23
DATE(NOW()) + 3 days | city1 | city2 | 13.23
...
DATE(NOW()) + 365 days | city1 | city2 | 13.23
(date, from_city, to_city)
是表的主键,我每天都会更新表,所以如果键已经存在一行,就应该替换它。
进行这些插入/更新的最佳方法是什么?最坏的情况,因为我必须从 java 程序中执行此操作,我将不得不创建 365 行并进行大批量插入:
INSERT INTO my_table
VALUES
(DATE(NOW()), city1, city2, 13.23),
(DATE(NOW() + INTERVAL '1' day), city1, city2, 13.23),
(DATE(NOW() + INTERVAL '2' day), city1, city2, 13.23),
...
问题:
-
最好的方法是什么?
在这种情况下,我是否可以避免这些插入并创建视图来返回每个城市对未来 365 天预计的最新可用日期?如何创建这样的视图?
【问题讨论】:
这些费率每天都不同吗?如果不是,我会质疑每天 1 行的设计,并且可能会使用范围之类的东西,即放置开始(如果需要,结束)日期。如果您想获取某一天的费率,则可以查询其开始日期最接近该天但仍早于该天或同一天的行。这样一来,所有日子都具有相同费率的示例只会导致 1 个条目。 @Thomas 好点,但不幸的是,它们每天都会有所不同。 也许城市对应该移动到父表中?city_pair
表中的每一行在rate
表中都有零、一或多行?
【参考方案1】:
您可以为此使用generate_series()
:
INSERT INTO my_table (date, from_city, to_city, rate_per_mile)
select g.dt::date, 'city1', 'city2', 13.12
from generate_series(current_date, current_date + 364, interval '1 day') as g(dt);
【讨论】:
@daltonfury42:你想要 365 天还是真的想要 1 年。他们是不一样的; 365 天在大约 75% 的时间里是正确的。如果您总是想要一整年,请使用 generate_series(current_date, current_date + interval '1 year' - interval '1 day', interval '1 day) as g(dt)【参考方案2】:由于您必须从 Java 中执行此操作,因此创建一个循环并使用批处理以获得更好的性能。
LocalDate today = LocalDate.now();
String fromCity = "city1";
String toCity = "city2";
BigDecimal ratePerMile = new BigDecimal("13.23");
try (Connection con = DriverManager.getConnection("..."))
String sql = "INSERT INTO my_table ( date, from_city, to_city, rate_per_mile ) VALUES (?,?,?,?)";
try (PreparedStatement stmt = con.prepareStatement(sql))
for (int daysToAdd = 0; daysToAdd <= 365; daysToAdd++)
LocalDate date = today.plusDays(daysToAdd);
stmt.setObject(1, date);
stmt.setString(2, fromCity);
stmt.setString(3, toCity);
stmt.setBigDecimal(4, ratePerMile);
stmt.addBatch();
stmt.executeBatch();
如果 JDBC 驱动程序不喜欢 LocalDate
,请改用此行:
stmt.setDate(1, java.sql.Date.valueOf(date));
【讨论】:
是的,如果没有纯 SQL/DB 解决方案,这就是我必须要做的。以上是关于如何插入 365 行并为每一行增加一天的日期的主要内容,如果未能解决你的问题,请参考以下文章