Простое решение: применить функцию idxmax (), чтобы получить индексы строк с максимальными значениями. Это отфильтровывало бы все строки с максимальным значением в группе.
In [365]: import pandas as pd
In [366]: df = pd.DataFrame({
'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4','MM4'],
'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
'count' : [3,2,5,8,10,1,2,2,7]
})
In [367]: df
Out[367]:
count mt sp val
0 3 S1 MM1 a
1 2 S1 MM1 n
2 5 S3 MM1 cb
3 8 S3 MM2 mk
4 10 S4 MM2 bg
5 1 S4 MM2 dgb
6 2 S2 MM4 rd
7 2 S2 MM4 cb
8 7 S2 MM4 uyi
### Apply idxmax() and use .loc() on dataframe to filter the rows with max values:
In [368]: df.loc[df.groupby(["sp", "mt"])["count"].idxmax()]
Out[368]:
count mt sp val
0 3 S1 MM1 a
2 5 S3 MM1 cb
3 8 S3 MM2 mk
4 10 S4 MM2 bg
8 7 S2 MM4 uyi
### Just to show what values are returned by .idxmax() above:
In [369]: df.groupby(["sp", "mt"])["count"].idxmax().values
Out[369]: array([0, 2, 3, 4, 8])
Похоже, что вы выполнили другой оператор в том же соединении, прежде чем пересечь результирующий набор из первого оператора. Если вы размещаете обработку двух наборов результатов из одной базы данных, вы делаете что-то неправильно. Комбинация этих наборов должна выполняться на стороне базы данных.
Кроме того, у каждого оператора может быть только один результирующий набор. Поэтому, если вы повторяете два набора результатов одновременно, убедитесь, что они выполняются в разных операторах. Открытие второго результирующего набора в одном выражении косвенно закрывает первое. http://java.sun.com/javase/6/docs/api/java/sql/Statement.html
У меня такая же ошибка, все было правильно, только я использовал тот же объект интерфейса оператора для выполнения и обновления базы данных. После разделения, то есть с использованием разных объектов интерфейса оператора для обновления и выполнения запроса, я решил эту ошибку. то есть избавиться от этого, не используйте один и тот же объект-оператор для обновления и выполнения запроса.
Исключение указывает, что ваш результат закрыт. Вы должны изучить свой код и посмотреть все места, где вы вызываете вызов ResultSet.close()
. Также найдите Statement.close()
и Connection.close()
. Конечно, один из них вызывается до того, как вызывается rs.next()
.
Проверьте, был ли вы объявлен метод, в котором этот код выполняется как static
. Если это static
, может быть какой-то другой поток, сбросив ResultSet
.
Это может быть вызвано рядом причин, включая драйвер, который вы используете.
a) Некоторые драйверы не допускают вложенных операторов. В зависимости от того, поддерживает ли ваш драйвер JDBC 3.0, вы должны проверить третий параметр при создании объекта Statement. Например, у меня была такая же проблема с драйвером JayBird для Firebird, но код работал нормально с драйвером postgres. Затем я добавил третий параметр к вызову метода createStatement и установил его в ResultSet.HOLD_CURSORS_OVER_COMMIT, и код начал нормально работать и для Firebird.
static void testNestedRS() throws SQLException {
Connection con =null;
try {
// GET A CONNECTION
con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
String sql1 = "select * from reportes_clasificacion";
Statement st1 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs1 = null;
try {
// EXECUTE THE FIRST QRY
rs1 = st1.executeQuery(sql1);
while (rs1.next()) {
// THIS LINE WILL BE PRINTED JUST ONCE ON
// SOME DRIVERS UNLESS YOU CREATE THE STATEMENT
// WITH 3 PARAMETERS USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
System.out.println("ST1 Row #: " + rs1.getRow());
String sql2 = "select * from reportes";
Statement st2 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// EXECUTE THE SECOND QRY. THIS CLOSES THE FIRST
// ResultSet ON SOME DRIVERS WITHOUT USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
st2.executeQuery(sql2);
st2.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
rs1.close();
st1.close();
}
} catch (SQLException e) {
} finally {
con.close();
}
}
b) В вашем коде может быть ошибка. Помните, что вы не можете повторно использовать объект Statement, как только вы повторно выполняете запрос в одном и том же объекте оператора, все открытые результирующие группы, связанные с оператором, будут закрыты. Убедитесь, что вы не закрываете оператор.
ResultSet.HOLD_CURSORS_OVER_COMMIT
.
– Indrek Kõue
27 December 2011 в 15:19
убедитесь, что вы закрыли все свои утверждения и результирующие наборы перед запуском rs.next. Finaly гарантирует это
public boolean flowExists( Integer idStatusPrevious, Integer idStatus, Connection connection ) {
LogUtil.logRequestMethod();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement( Constants.SCRIPT_SELECT_FIND_FLOW_STATUS_BY_STATUS );
ps.setInt( 1, idStatusPrevious );
ps.setInt( 2, idStatus );
rs = ps.executeQuery();
Long count = 0L;
if ( rs != null ) {
while ( rs.next() ) {
count = rs.getLong( 1 );
break;
}
}
LogUtil.logSuccessMethod();
return count > 0L;
} catch ( Exception e ) {
String errorMsg = String
.format( Constants.ERROR_FINALIZED_METHOD, ( e.getMessage() != null ? e.getMessage() : "" ) );
LogUtil.logError( errorMsg, e );
throw new FatalException( errorMsg );
} finally {
rs.close();
ps.close();
}
Правильный вызов jdbc должен выглядеть примерно так:
try {
Connection conn;
Statement stmt;
ResultSet rs;
try {
conn = DriverManager.getConnection(myUrl,"","");
stmt = conn.createStatement();
rs = stmt.executeQuery(myQuery);
while ( rs.next() ) {
// process results
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
} finally {
// you should release your resources here
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
вы можете закрыть соединение (или оператор) только после получения результата из набора результатов. Самый безопасный способ - сделать это в блоке finally
. Однако close()
также мог бы работать SqlException
, следовательно, другой блок try-catch
.
Возможно, вы закрыли либо Connection
, либо Statement
, которые сделали ResultSet
, что приведет к закрытию ResultSet
.