const { Client } = require('pg'); async function main() { const conn = new Client({ host: 'localhost', port: 5432, user: 'postgres', password: 'turbo123', database: 'genome_db' }); await conn.connect(); const farmNo = 1; const cowId = 'KOR002191643715'; console.log('======================================================='); console.log('대시보드 vs 개체상세 차트 비교'); console.log('=======================================================\n'); // ===================================================== // 1. 대시보드: getFarmRegionRanking API // - 농가 평균 = 농가 내 개체들의 선발지수 평균 // - 보은군 평균 = 전체 개체들의 선발지수 평균 // ===================================================== console.log('=== 1. 대시보드 (getFarmRegionRanking) ==='); console.log('보은군 내 농가 위치 차트\n'); // 모든 개체별 선발지수 (35개 형질 EBV 합계) const allCowsResult = await conn.query(` SELECT c.cow_id, gr.fk_farm_no, SUM(gtd.trait_ebv) as total_ebv FROM tb_genome_request gr JOIN tb_cow c ON gr.fk_cow_no = c.pk_cow_no JOIN tb_genome_trait_detail gtd ON gtd.cow_id = c.cow_id AND gtd.del_dt IS NULL WHERE gr.del_dt IS NULL AND c.del_dt IS NULL AND gr.chip_sire_name = '일치' GROUP BY c.cow_id, gr.fk_farm_no HAVING COUNT(*) = 35 `); const allCows = allCowsResult.rows; // 농가별 평균 계산 const farmScoresMap = new Map(); for (const cow of allCows) { const fNo = cow.fk_farm_no; if (!farmScoresMap.has(fNo)) { farmScoresMap.set(fNo, []); } farmScoresMap.set(fNo, [...farmScoresMap.get(fNo), Number(cow.total_ebv)]); } // 농가별 평균 const farmAverages = []; for (const [fNo, scores] of farmScoresMap.entries()) { const avg = scores.reduce((a, b) => a + b, 0) / scores.length; farmAverages.push({ farmNo: fNo, avgScore: avg, cowCount: scores.length }); } farmAverages.sort((a, b) => b.avgScore - a.avgScore); // 보은군 전체 평균 (개체별 합계의 평균) const regionAvgScore_dashboard = allCows.reduce((sum, c) => sum + Number(c.total_ebv), 0) / allCows.length; // 농가 1번 평균 const myFarm = farmAverages.find(f => f.farmNo === farmNo); const farmAvgScore_dashboard = myFarm?.avgScore || 0; console.log('농가 평균 (개체 선발지수 평균):', farmAvgScore_dashboard.toFixed(2)); console.log('보은군 평균 (개체 선발지수 평균):', regionAvgScore_dashboard.toFixed(2)); console.log('차이 (농가 - 보은군):', (farmAvgScore_dashboard - regionAvgScore_dashboard).toFixed(2)); // ===================================================== // 2. 개체 상세: getSelectionIndex API // - 내 개체 = 개체의 선발지수 (35개 형질 EBV 합계) // - 농가 평균 = 같은 농가 개체들의 선발지수 평균 // - 보은군 평균 = 전체 개체들의 선발지수 평균 // ===================================================== console.log('\n=== 2. 개체 상세 (getSelectionIndex) ==='); console.log('농가 및 보은군 내 개체 위치 차트\n'); // 내 개체 선발지수 const myCow = allCows.find(c => c.cow_id === cowId); const myScore = myCow ? Number(myCow.total_ebv) : 0; // 같은 농가 개체들의 평균 const farmCows = allCows.filter(c => c.fk_farm_no === farmNo); const farmAvgScore_detail = farmCows.reduce((sum, c) => sum + Number(c.total_ebv), 0) / farmCows.length; // 보은군 전체 평균 const regionAvgScore_detail = regionAvgScore_dashboard; // 동일 console.log('내 개체 선발지수:', myScore.toFixed(2)); console.log('농가 평균:', farmAvgScore_detail.toFixed(2)); console.log('보은군 평균:', regionAvgScore_detail.toFixed(2)); console.log(''); console.log('내 개체 vs 농가평균:', (myScore - farmAvgScore_detail).toFixed(2)); console.log('내 개체 vs 보은군평균:', (myScore - regionAvgScore_detail).toFixed(2)); // ===================================================== // 3. 비교 요약 // ===================================================== console.log('\n======================================================='); console.log('비교 요약'); console.log('======================================================='); console.log(''); console.log('[대시보드] 농가 vs 보은군 차이:', (farmAvgScore_dashboard - regionAvgScore_dashboard).toFixed(2)); console.log('[개체상세] 개체 vs 농가 차이:', (myScore - farmAvgScore_detail).toFixed(2)); console.log('[개체상세] 개체 vs 보은군 차이:', (myScore - regionAvgScore_detail).toFixed(2)); console.log(''); console.log('=> 대시보드는 농가평균 vs 보은군평균 비교 (차이 작음)'); console.log('=> 개체상세는 개별개체 vs 평균 비교 (개체가 우수하면 차이 큼)'); await conn.end(); } main().catch(console.error);