
Я хочу сопоставить записи из таблицы CUSTOMER с записями в таблице TRANSACTION.
Раньше мы полагались исключительно на Поле CUSTOMER_ID для сопоставления.
Однако мы заметили, что таблица TRANSACTION содержит несколько записей с одним и тем же CUSTOMER_ID. Чтобы решить эту проблему, нам необходимо определить алгоритм, который может обрабатывать случаи, когда существует несколько совпадающих записей для одного и того же CUSTOMER_ID.
Решение должно соответствовать следующим критериям:
- TRANSACTION.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID.
- SUBSTR(TRANSACTION.ACCOUNT_NUMBER, INSTR(TRANSACTION.ACCOUNT_NUMBER, '.') + 1) = CUSTOMER.ACCOUNT_NUMBER.
- TRANSACTION.ADDRESS = CUSTOMER.ADDRESS (это условие должно быть необязательным, если поле ADDRESS существует).
- В случаях совпадения нескольких строк выберите транзакцию с самой ранней ISSUE_DATE при условии, что CUSTOMER.CREATED_AT {
StringBuffer qryStr = new StringBuffer() //
.append(
"SELECT "
+ " er.CUSTOMER_ID, "
+ " er1.ID, "
+ " er1.DESCRIPTION, "
+ " er1.REFERENCE_NUMBER, "
+ " er1.CATEGORY "
+ " FROM TRANSACTION er "
+ " INNER JOIN DETAILS er1 "
+ " ON (er.ID = er1.EM_ID) "
+ " WHERE "
);
String inCustomerIdList = NativeQuerySupport.inClause(batch);
qryStr.append(" er.CUSTOMER_ID IN ").append(inCustomerIdList);
Query query = em.createNativeQuery(qryStr.toString());
results.addAll(query.getResultList());
});
ret = results.stream()
.map(erm -> Details.toModel(erm))
.collect(Collectors.toList());
return ret;
}
[/code]
Итак, я думаю, что параметром метода должен быть список всех полей CUSTOMER.При описанном выше подходе мне нужно выполнить столько запросов, сколько существует критериев, что сводит на нет преимущества производительности, полученные от пакетной обработки в предыдущей реализации.Код: Выделить всё
public List searchTransactions(List criteria) and the query to be as below StringBuffer qryStr = new StringBuffer() // .append( "SELECT " + " er.CUSTOMER_ID, " + " er1.ID, " + " er1.DESCRIPTION, " + " er1.REFERENCE_NUMBER, " + " er1.CATEGORY " + " FROM TRANSACTION er " + " INNER JOIN DETAILS er1 " + " ON (er.ID = er1.EM_ID) " + " WHERE er.CUSTOMER_ID = ?customerId " + " AND SUBSTR(er.ACCOUNT_NUMBER, INSTR(er.ACCOUNT_NUMBER, '.') + 1) = ?accountNumber " + " AND (er.ADDRESS = ?address OR ?address IS NULL ) " + " AND er.ISSUE_DATE = ( " + " SELECT MIN(em2.ISSUE_DATE) " + " FROM TRANSACTION em2 " + " WHERE er.CUSTOMER_ID = em2.CUSTOMER_ID " + " AND er.ACCOUNT_NUMBER = em2.ACCOUNT_NUMBER " + " AND (er.ADDRESS = em2.ADDRESS OR ?address IS NULL )" + " AND em2.ISSUE_DATE >= ?createdAt)"); Query query = em.createNativeQuery(qryStr.toString()); query.setParameter("customerId", criteria.getCustomerId()); query.setParameter("accountNumber", criteria.getAccountNumber()); query.setParameter("address", criteria.getAddress()); query.setParameter("createdAt", criteria.getCreatedAt());
Есть ли лучший способ справиться с этим?
Например, можем ли мы использовать предыдущий запрос для получения всех необходимых данных, а затем, в случае дублирования CUSTOMER_ID, сделать второй запрос для разрешения конфликтов?
Подробнее здесь: https://stackoverflow.com/questions/793 ... stomer-ids