2015-12-18 4 views
-1

У меня есть набор результатов, который возвращает список (повторяющихся) имен с некоторыми условиями sql, связанными с этим именем. Это набор результатов из 2 столбцов. Это выглядит следующим образом:Пользовательская итерация по JDBC ResultSet

____________________________________ 
|id    |  data  | 
|__________________________________| 
|john    | sql1   | 
|john    | sql2   | 
|adam    | sql1   | 
|jack    | sql3   | 
|jack    | sql2   | 
____________________________________ 

То, что я хотел бы, чтобы построить SQL запрос, который выглядит следующим образом:

select *, 'john' as id from table_x where sql1 or sql2 
union 
select *, 'adam' as id table_x where sql1 
union 
select *, 'jack' as id from table_x where sql3 or sql2; 

Возможно ли это просто с помощью res.next() в то время петля и делать там какую-то магию? Я думал об использовании 2-мерного массива или карты, чтобы сначала сохранить набор результатов, а затем перебрать это, чтобы это сделать, но хотел знать, есть ли какие-либо более легкие способы сделать это.

+0

@Andreas: Можете ли вы указать мне правильное направление относительно проверки на изменение значения 'id'? Благодаря! :) – CodingInCircles

+0

Преобразованный комментарий к ответу. – Andreas

+0

Какова ваша платформа БД? Я предполагаю, что sql1 и sql2 являются предикатами (col_name = value)? – slambeth

ответ

2

Похоже, что у impala есть функция group_concat, поэтому вы можете использовать это, чтобы сгладить шаг.

(table_y быть таблицы, ваш первоначальный набор результатов пришел из

select id, group_concat(data) as predicates from table_y group by id; 

Тогда просто петля через них:.

String sql; 
    while(rs.next()) { 
     String rPredicates = rs.getString("predicates").split(","); 
     sql = "SELECT *, " + rs.getString("id") + " FROM table_x WHERE " 
     sql += rPredicates[0]; 
     for(int ndx=1; ndx< rPredicates.length; ndx++) { 
     sql += " or " + rPredicates[ndx]; 
     } 
     sql += " union "; 
    } 

Это проверялось, но вы получите точку Вы могли бы устранить некоторые линии, используя StringUtils.join или .collapse что-то simlar. Существует много классов струнных utils.

Если вы достаточно старались, возможно, e это чисто с SQL, но это немного лучше, по крайней мере.

EDIT: Я один до этого, вы можете поставить Seperator к GROUP_CONCAT, так что вы могли бы выполнить этот SQL, чтобы начать

select id, group_concat(date, ' or ') as predicates from table_y; 

Тогда вам не придется собирать предикаты , просто добавьте все это.

+0

Это выглядит неплохо! Спасибо за ваш ответ :) Я попробую и выберет один. – CodingInCircles

+0

Holy SQL Batman! Это редактирование было потрясающим! У меня уже был код для объединения (даже до ответа @Andreas). С этим запросом мне не нужно менять код один бит! И думать, все, что мне нужно было сделать, это RTFM! : P Большое спасибо! : D – CodingInCircles

+1

@CodingInCircles Очень важной информацией для этого решения был поставщик СУБД (Impala). Это отличное решение для конкретного поставщика, в то время как мой ответ будет работать для всех поставщиков СУБД. * + 1 для простого решения. * – Andreas

1

Вы получите единый результирующий набор, являющийся объединением всех 3 выбранных. Если вы хотите классифицировать по столбцу id, вы просто перебираете результат и обрабатываете текущую строку на основе значения столбца id (например, используйте значение id в качестве ключа в карте).

+0

Я думаю, вы неправильно поняли мой вопрос. У меня уже есть набор результатов, который является столбцом идентификаторов и данных. Используя это, я хочу построить запрос, как показано. – CodingInCircles

+0

ОК, я думаю, что я рядом. Вы бы построили карту с значением столбца id в качестве ключа и список значений данных в качестве значений, затем используйте эту карту для построения каждого выбора. – DBug

2

Да, это возможно.

Если вы отсортируете запрос по id, вы можете использовать обычный цикл и проверить на изменение значения id. Нет необходимости в 2D-массиве или Map, всего лишь StringBuilder для постепенного построения SQL-запроса.

String prevId = null; 
StringBuilder sql = new StringBuilder(); 
while (rs.next()) { 
    String id = rs.getString("id"); 
    String data = rs.getString("data"); 
    if (id.equals(prevId)) { 
     sql.append(" or "); 
    } else { 
     if (prevId != null) 
      sql.append(" union "); 
     sql.append("select *, '") 
      .append(id) // may need to SQL escape value 
      .append("' as id from table_x where "); 
     prevId = id; 
    } 
    sql.append(data); 
} 
+0

Использование StringJoiner для UNION между ними может быть забавным. – Jan

+0

Спасибо за это. Я дам ему шанс и приму это после тестирования. Благодаря! :) – CodingInCircles

Смежные вопросы