feat: Enhance MasterDetailExcelService with table alias for JOIN operations
- Added a new property `tableAlias` to distinguish between master ("m") and detail ("d") tables during JOIN operations.
- Updated the SELECT clause to include the appropriate table alias for master and detail tables.
- Improved the entity join clause construction to utilize the new table alias, ensuring clarity in SQL queries.
This commit is contained in:
@@ -310,6 +310,7 @@ class MasterDetailExcelService {
|
||||
sourceColumn: string;
|
||||
alias: string;
|
||||
displayColumn: string;
|
||||
tableAlias: string; // "m" (마스터) 또는 "d" (디테일) - JOIN 시 소스 테이블 구분
|
||||
}> = [];
|
||||
|
||||
// SELECT 절 구성
|
||||
@@ -332,6 +333,7 @@ class MasterDetailExcelService {
|
||||
sourceColumn: fkColumn.sourceColumn,
|
||||
alias,
|
||||
displayColumn,
|
||||
tableAlias: "m", // 마스터 테이블에서 조인
|
||||
});
|
||||
selectParts.push(`${alias}."${displayColumn}" AS "${col.name}"`);
|
||||
} else {
|
||||
@@ -360,6 +362,7 @@ class MasterDetailExcelService {
|
||||
sourceColumn: fkColumn.sourceColumn,
|
||||
alias,
|
||||
displayColumn,
|
||||
tableAlias: "d", // 디테일 테이블에서 조인
|
||||
});
|
||||
selectParts.push(`${alias}."${displayColumn}" AS "${col.name}"`);
|
||||
} else {
|
||||
@@ -373,9 +376,9 @@ class MasterDetailExcelService {
|
||||
|
||||
const selectClause = selectParts.join(", ");
|
||||
|
||||
// 엔티티 조인 절 구성
|
||||
// 엔티티 조인 절 구성 (마스터/디테일 테이블 alias 구분)
|
||||
const entityJoinClauses = entityJoins.map(ej =>
|
||||
`LEFT JOIN "${ej.refTable}" ${ej.alias} ON m."${ej.sourceColumn}" = ${ej.alias}."${ej.refColumn}"`
|
||||
`LEFT JOIN "${ej.refTable}" ${ej.alias} ON ${ej.tableAlias}."${ej.sourceColumn}" = ${ej.alias}."${ej.refColumn}"`
|
||||
).join("\n ");
|
||||
|
||||
// WHERE 절 구성
|
||||
|
||||
@@ -1371,39 +1371,66 @@ class TableCategoryValueService {
|
||||
|
||||
const pool = getPool();
|
||||
|
||||
// 동적으로 파라미터 플레이스홀더 생성
|
||||
const placeholders = valueCodes.map((_, i) => `$${i + 1}`).join(", ");
|
||||
const n = valueCodes.length;
|
||||
|
||||
// 첫 번째 쿼리용 플레이스홀더: $1 ~ $n
|
||||
const placeholders1 = valueCodes.map((_, i) => `$${i + 1}`).join(", ");
|
||||
|
||||
let query: string;
|
||||
let params: any[];
|
||||
|
||||
if (companyCode === "*") {
|
||||
// 최고 관리자: 모든 카테고리 값 조회
|
||||
// 최고 관리자: 두 테이블 모두에서 조회 (UNION으로 병합)
|
||||
// 두 번째 쿼리용 플레이스홀더: $n+1 ~ $2n
|
||||
const placeholders2 = valueCodes.map((_, i) => `$${n + i + 1}`).join(", ");
|
||||
query = `
|
||||
SELECT value_code, value_label
|
||||
FROM table_column_category_values
|
||||
WHERE value_code IN (${placeholders})
|
||||
AND is_active = true
|
||||
SELECT value_code, value_label FROM (
|
||||
SELECT value_code, value_label
|
||||
FROM table_column_category_values
|
||||
WHERE value_code IN (${placeholders1})
|
||||
AND is_active = true
|
||||
UNION ALL
|
||||
SELECT value_code, value_label
|
||||
FROM category_values
|
||||
WHERE value_code IN (${placeholders2})
|
||||
AND is_active = true
|
||||
) combined
|
||||
`;
|
||||
params = valueCodes;
|
||||
params = [...valueCodes, ...valueCodes];
|
||||
} else {
|
||||
// 일반 회사: 자신의 카테고리 값 + 공통 카테고리 값 조회
|
||||
// 일반 회사: 두 테이블에서 자신의 카테고리 값 + 공통 카테고리 값 조회
|
||||
// 첫 번째: $1~$n (valueCodes), $n+1 (companyCode)
|
||||
// 두 번째: $n+2~$2n+1 (valueCodes), $2n+2 (companyCode)
|
||||
const companyIdx1 = n + 1;
|
||||
const placeholders2 = valueCodes.map((_, i) => `$${n + 1 + i + 1}`).join(", ");
|
||||
const companyIdx2 = 2 * n + 2;
|
||||
|
||||
query = `
|
||||
SELECT value_code, value_label
|
||||
FROM table_column_category_values
|
||||
WHERE value_code IN (${placeholders})
|
||||
AND is_active = true
|
||||
AND (company_code = $${valueCodes.length + 1} OR company_code = '*')
|
||||
SELECT value_code, value_label FROM (
|
||||
SELECT value_code, value_label
|
||||
FROM table_column_category_values
|
||||
WHERE value_code IN (${placeholders1})
|
||||
AND is_active = true
|
||||
AND (company_code = $${companyIdx1} OR company_code = '*')
|
||||
UNION ALL
|
||||
SELECT value_code, value_label
|
||||
FROM category_values
|
||||
WHERE value_code IN (${placeholders2})
|
||||
AND is_active = true
|
||||
AND (company_code = $${companyIdx2} OR company_code = '*')
|
||||
) combined
|
||||
`;
|
||||
params = [...valueCodes, companyCode];
|
||||
params = [...valueCodes, companyCode, ...valueCodes, companyCode];
|
||||
}
|
||||
|
||||
const result = await pool.query(query, params);
|
||||
|
||||
// { [code]: label } 형태로 변환
|
||||
// { [code]: label } 형태로 변환 (중복 시 첫 번째 결과 우선)
|
||||
const labels: Record<string, string> = {};
|
||||
for (const row of result.rows) {
|
||||
labels[row.value_code] = row.value_label;
|
||||
if (!labels[row.value_code]) {
|
||||
labels[row.value_code] = row.value_label;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`카테고리 라벨 ${Object.keys(labels).length}개 조회 완료`, { companyCode });
|
||||
|
||||
Reference in New Issue
Block a user