You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用node-postgres从PostgreSQL的COUNTRIES和CITIES表查询嵌套结构数据?

当然可以!想要生成你需要的这种嵌套结构数据,我们有两种实用的实现方式,根据你的数据量大小来选就行:

方法一:分步查询(简单直观)

这种方式先查询所有国家,再逐个查询每个国家对应的城市,逻辑清晰,适合数据量不大的场景:

const { Client } = require('pg');

async function getCountriesWithCities() {
  const client = new Client({
    // 填写你的数据库连接配置
    user: 'your_user',
    host: 'your_host',
    database: 'your_db',
    password: 'your_password',
    port: 5432,
  });

  try {
    await client.connect();
    
    // 第一步:查询所有国家数据
    const countriesResult = await client.query('SELECT id, name FROM countries');
    const countries = countriesResult.rows;

    // 第二步:给每个国家关联对应的城市
    for (const country of countries) {
      const citiesResult = await client.query(
        'SELECT id, name FROM cities WHERE country_id = $1',
        [country.id]
      );
      // 组装成目标结构
      country.cities = citiesResult.rows.map(city => ({
        id: city.id,
        city: city.name
      }));
      // 调整字段名符合要求
      country.country = country.name;
      delete country.name;
    }

    return countries;
  } catch (err) {
    console.error('查询出错:', err);
    throw err;
  } finally {
    await client.end();
  }
}

// 调用函数查看结果
getCountriesWithCities().then(data => console.log(data));
方法二:JOIN查询后聚合(性能更优)

如果你的国家和城市数据量较大,多次查询数据库会影响性能,这时候可以用一次SQL JOIN查询,然后在代码里把数据聚合嵌套起来,减少数据库交互次数:

const { Client } = require('pg');

async function getCountriesWithCities() {
  const client = new Client({
    // 填写你的数据库连接配置
    user: 'your_user',
    host: 'your_host',
    database: 'your_db',
    password: 'your_password',
    port: 5432,
  });

  try {
    await client.connect();
    
    // 一次JOIN查询所有国家及关联城市
    const result = await client.query(`
      SELECT 
        c.id AS country_id, 
        c.name AS country, 
        ci.id AS city_id, 
        ci.name AS city
      FROM countries c
      LEFT JOIN cities ci ON c.id = ci.country_id
    `);

    // 用对象映射国家,方便聚合城市数据
    const countriesMap = {};
    result.rows.forEach(row => {
      // 初始化未存在的国家条目
      if (!countriesMap[row.country_id]) {
        countriesMap[row.country_id] = {
          id: row.country_id,
          country: row.country,
          cities: []
        };
      }
      // 存在城市数据时,添加到对应国家的cities数组
      if (row.city_id) {
        countriesMap[row.country_id].cities.push({
          id: row.city_id,
          city: row.city
        });
      }
    });

    // 把映射对象转为目标数组格式
    return Object.values(countriesMap);
  } catch (err) {
    console.error('查询出错:', err);
    throw err;
  } finally {
    await client.end();
  }
}

// 调用函数查看结果
getCountriesWithCities().then(data => console.log(data));

两种方式最终都会输出你需要的嵌套结构,方法二更适合生产环境的大数据量场景,因为只需要和数据库交互一次,减少了网络开销。

内容的提问来源于stack exchange,提问作者Oleg Ovcharenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:17:30