У меня есть схема, похожая на показанную, и мне нужно получить информацию о транзакции.
Я хочу сопоставить записи из таблицы CUSTOMER с записями в таблице TRANSACTION.
Раньше мы полагались исключительно на Поле CUSTOMER_ID для сопоставления.
Однако мы заметили, что таблица TRANSACTION содержит несколько записей с одним и тем же CUSTOMER_ID. Чтобы решить эту проблему, нам необходимо определить алгоритм, который может обрабатывать случаи, когда существует несколько совпадающих записей для одного и того же CUSTOMER_ID.
Решение должно соответствовать следующим критериям:
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, сделать второй запрос для разрешения конфликтов?
У меня есть схема, похожая на показанную, и мне нужно получить информацию о транзакции. [img]https://i.sstatic.net/xVhLpCri.jpg[/img]
Я хочу сопоставить записи из таблицы CUSTOMER с записями в таблице TRANSACTION. Раньше мы полагались исключительно на Поле CUSTOMER_ID для сопоставления. Однако мы заметили, что таблица TRANSACTION содержит несколько записей с одним и тем же CUSTOMER_ID. Чтобы решить эту проблему, нам необходимо определить алгоритм, который может обрабатывать случаи, когда существует несколько совпадающих записей для одного и того же CUSTOMER_ID. Решение должно соответствовать следующим критериям: [list] [*]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 " );
ret = results.stream() .map(erm -> Details.toModel(erm)) .collect(Collectors.toList());
return ret; } [/code] Итак, я думаю, что параметром метода должен быть список всех полей CUSTOMER. [code]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()); [/code] При описанном выше подходе мне нужно выполнить столько запросов, сколько существует критериев, что сводит на нет преимущества производительности, полученные от пакетной обработки в предыдущей реализации. Есть ли лучший способ справиться с этим? Например, можем ли мы использовать предыдущий запрос для получения всех необходимых данных, а затем, в случае дублирования CUSTOMER_ID, сделать второй запрос для разрешения конфликтов?