如何用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
相关产品推荐
相关产品推荐

