简体   繁体   中英

How to insert 365 rows and increment date by one day for each row

I have a table with the schema like this:

date | from_city | to_city | rate_per_mile 

I want to insert today's rate for a city pair (city1, city2, rate) and create 365 rows for all days starting from today until the next 365 days.

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) is the primary key for the table, and I would be updating the table every day, so if a row already exists for the key, it should be replaced.

What is the best possible way to do these insert/updates? Worst case since I have to do this from a java program, I'll have to create 365 rows and do a big bulk insert:

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),
  ...

Questions:

  1. What is the best way to do this?
  2. In such situations, can I avoid these inserts and create views instead that would return the latest available date projected for next 365 days for each city pair? How to create such a view?

You can use generate_series() for this:

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);

Since you have to do this from Java, create a loop, and use batching for better performance.

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();
    }
}

If the JDBC driver doesn't like LocalDate , use this line instead:

stmt.setDate(1, java.sql.Date.valueOf(date));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM