fix: 카테고리 컬럼 중복 데이터 문제 해결
- table_column_category_values JOIN 시 회사 데이터만 사용하도록 수정 - 공통 데이터(company_code='*') 사용 금지 - is_active=true 필터 추가로 활성화된 카테고리만 조회 - entityJoinService.ts의 buildJoinQuery 및 buildCountQuery 수정 - 품목 정보 테이블 등에서 발생하던 2배 중복 문제 해결
This commit is contained in:
@@ -223,12 +223,14 @@ export class EntityJoinService {
|
||||
const aliasMap = new Map<string, string>();
|
||||
const usedAliasesForColumns = new Set<string>();
|
||||
|
||||
// joinConfigs를 참조 테이블별로 중복 제거하여 별칭 생성
|
||||
// joinConfigs를 참조 테이블 + 소스 컬럼별로 중복 제거하여 별칭 생성
|
||||
// (table_column_category_values는 같은 테이블이라도 sourceColumn마다 별도 JOIN 필요)
|
||||
const uniqueReferenceTableConfigs = joinConfigs.reduce((acc, config) => {
|
||||
if (
|
||||
!acc.some(
|
||||
(existingConfig) =>
|
||||
existingConfig.referenceTable === config.referenceTable
|
||||
existingConfig.referenceTable === config.referenceTable &&
|
||||
existingConfig.sourceColumn === config.sourceColumn
|
||||
)
|
||||
) {
|
||||
acc.push(config);
|
||||
@@ -237,7 +239,7 @@ export class EntityJoinService {
|
||||
}, [] as EntityJoinConfig[]);
|
||||
|
||||
logger.info(
|
||||
`🔧 별칭 생성 시작: ${uniqueReferenceTableConfigs.length}개 고유 테이블`
|
||||
`🔧 별칭 생성 시작: ${uniqueReferenceTableConfigs.length}개 고유 테이블+컬럼 조합`
|
||||
);
|
||||
|
||||
uniqueReferenceTableConfigs.forEach((config) => {
|
||||
@@ -250,13 +252,16 @@ export class EntityJoinService {
|
||||
counter++;
|
||||
}
|
||||
usedAliasesForColumns.add(alias);
|
||||
aliasMap.set(config.referenceTable, alias);
|
||||
logger.info(`🔧 별칭 생성: ${config.referenceTable} → ${alias}`);
|
||||
// 같은 테이블이라도 sourceColumn이 다르면 별도 별칭 생성 (table_column_category_values 대응)
|
||||
const aliasKey = `${config.referenceTable}:${config.sourceColumn}`;
|
||||
aliasMap.set(aliasKey, alias);
|
||||
logger.info(`🔧 별칭 생성: ${config.referenceTable}.${config.sourceColumn} → ${alias}`);
|
||||
});
|
||||
|
||||
const joinColumns = joinConfigs
|
||||
.map((config) => {
|
||||
const alias = aliasMap.get(config.referenceTable);
|
||||
const aliasKey = `${config.referenceTable}:${config.sourceColumn}`;
|
||||
const alias = aliasMap.get(aliasKey);
|
||||
const displayColumns = config.displayColumns || [
|
||||
config.displayColumn,
|
||||
];
|
||||
@@ -346,14 +351,16 @@ export class EntityJoinService {
|
||||
// FROM 절 (메인 테이블)
|
||||
const fromClause = `FROM ${tableName} main`;
|
||||
|
||||
// LEFT JOIN 절들 (위에서 생성한 별칭 매핑 사용, 중복 테이블 제거)
|
||||
// LEFT JOIN 절들 (위에서 생성한 별칭 매핑 사용, 각 sourceColumn마다 별도 JOIN)
|
||||
const joinClauses = uniqueReferenceTableConfigs
|
||||
.map((config) => {
|
||||
const alias = aliasMap.get(config.referenceTable);
|
||||
const aliasKey = `${config.referenceTable}:${config.sourceColumn}`;
|
||||
const alias = aliasMap.get(aliasKey);
|
||||
|
||||
// table_column_category_values는 특별한 조인 조건 필요
|
||||
// table_column_category_values는 특별한 조인 조건 필요 (회사별 필터링만)
|
||||
if (config.referenceTable === 'table_column_category_values') {
|
||||
return `LEFT JOIN ${config.referenceTable} ${alias} ON main.${config.sourceColumn} = ${alias}.${config.referenceColumn} AND ${alias}.table_name = '${tableName}' AND ${alias}.column_name = '${config.sourceColumn}'`;
|
||||
// 멀티테넌시: 회사 데이터만 사용 (공통 데이터 제외)
|
||||
return `LEFT JOIN ${config.referenceTable} ${alias} ON main.${config.sourceColumn} = ${alias}.${config.referenceColumn} AND ${alias}.table_name = '${tableName}' AND ${alias}.column_name = '${config.sourceColumn}' AND ${alias}.company_code = main.company_code AND ${alias}.is_active = true`;
|
||||
}
|
||||
|
||||
return `LEFT JOIN ${config.referenceTable} ${alias} ON main.${config.sourceColumn} = ${alias}.${config.referenceColumn}`;
|
||||
@@ -538,12 +545,13 @@ export class EntityJoinService {
|
||||
const aliasMap = new Map<string, string>();
|
||||
const usedAliases = new Set<string>();
|
||||
|
||||
// joinConfigs를 참조 테이블별로 중복 제거하여 별칭 생성
|
||||
// joinConfigs를 참조 테이블 + 소스 컬럼별로 중복 제거하여 별칭 생성
|
||||
const uniqueReferenceTableConfigs = joinConfigs.reduce((acc, config) => {
|
||||
if (
|
||||
!acc.some(
|
||||
(existingConfig) =>
|
||||
existingConfig.referenceTable === config.referenceTable
|
||||
existingConfig.referenceTable === config.referenceTable &&
|
||||
existingConfig.sourceColumn === config.sourceColumn
|
||||
)
|
||||
) {
|
||||
acc.push(config);
|
||||
@@ -561,13 +569,22 @@ export class EntityJoinService {
|
||||
counter++;
|
||||
}
|
||||
usedAliases.add(alias);
|
||||
aliasMap.set(config.referenceTable, alias);
|
||||
const aliasKey = `${config.referenceTable}:${config.sourceColumn}`;
|
||||
aliasMap.set(aliasKey, alias);
|
||||
});
|
||||
|
||||
// JOIN 절들 (COUNT에서는 SELECT 컬럼 불필요)
|
||||
const joinClauses = uniqueReferenceTableConfigs
|
||||
.map((config) => {
|
||||
const alias = aliasMap.get(config.referenceTable);
|
||||
const aliasKey = `${config.referenceTable}:${config.sourceColumn}`;
|
||||
const alias = aliasMap.get(aliasKey);
|
||||
|
||||
// table_column_category_values는 특별한 조인 조건 필요 (회사별 필터링만)
|
||||
if (config.referenceTable === 'table_column_category_values') {
|
||||
// 멀티테넌시: 회사 데이터만 사용 (공통 데이터 제외)
|
||||
return `LEFT JOIN ${config.referenceTable} ${alias} ON main.${config.sourceColumn} = ${alias}.${config.referenceColumn} AND ${alias}.table_name = '${tableName}' AND ${alias}.column_name = '${config.sourceColumn}' AND ${alias}.company_code = main.company_code AND ${alias}.is_active = true`;
|
||||
}
|
||||
|
||||
return `LEFT JOIN ${config.referenceTable} ${alias} ON main.${config.sourceColumn} = ${alias}.${config.referenceColumn}`;
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
Reference in New Issue
Block a user