Executing multiple COUNT queries in Java - mysql

I have a MySQL database (ver. 5.2 CE) and I have a table which I want to filter into a another table based on the WHERE conditions given by the user (this comes from an array list). I want to perform count query on this new table for a split chosen by the user. For example, COUNT(*) from TableName WHERE [userConditions like gender=male and gender=female, etc]. The user can give more than one WHERE conditions but the COUNT query will only take one condition at a time. Hence, I made my method (which performs this query) an array to return multiple queries based on the number of conditions chosen by the user and then execute each query in a for loop. However, this seems to give me compilation errors in 2 ways: i) the way I return a built string in a String[] method and ii) the way I execute the COUNT query. The code for these problems:
private String countQuery;
public SetupSubsamplePopulation(UserSelectedSplit split) {
this.split = split;
// connect to the database
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?zeroDateTimeBehavior=convertToNull","root", "sharadha_1992");
String buildSelectQuery = buildSelectQueryForCode();
String getRowsFromTable = getNumberOfRows();
stmt = connection.createStatement();
rows = stmt.executeUpdate(buildSelectQuery);
ResultSet rs = stmt.executeQuery(getRowsFromTable);
for (int i=0; i<getCountOfWhereCondition().length; i++){
//where I get the executeQuery error
ResultSet rs1= stmt.execute(getCountOfWhereCondition());
while (rs1.next()){
rowsCount= rs.getRow();
rows_count++;
}
}
while (rs.next()) {
rows = rs.getRow();
rows_inserted++;
}
System.out.println(rows_inserted);
System.out.println(rows_count);
} catch (Exception e) {
e.printStackTrace();
}
}
The method which returns the array of COUNT queries:
public String[] getCountOfWhereCondition() {
countQuery="SELECT COUNT (*) FROM (SELECT * from mygrist_samples.subsample_population WHERE ";
for (int i = 0; i < split.getSplitConditions().size(); i++) {
String getCorrespondingCodeFromDatabase = split.getSplitConditions().get(i).getCode();
getCorrespondingCodeFromDatabase = getCorrespondingCodeFromDatabase.replaceAll("-", "_");
Enumerations enum1 = new Enumerations();
String getCorrespondingRelationshipOperator = enum1.getOperator(split.getSplitConditions().get(i).getRelationship());
countQuery+=getCorrespondingCodeFromDatabase + " " + getCorrespondingRelationshipOperator + " '" + split.getSplitConditions().get(i).getAnswer() + "'";
}
countQuery+=")";
System.out.println(countQuery);
//error which doesn't allow me to return a string
return countQuery;
}
Can someone please tell me how to implement this sensibly? Thank you very much.

I think you want conditional aggregation rather than a where:
select count(*)
from mygrist_samples.subsample_population
WHERE XXX
Is the same as:
select sum(case when XXX then 1 else 0 end) as cnt1
from mygrist_samples.subsample_population
Now you can add multiple conditions on one call:
select sum(case when XXX then 1 else 0 end) as cnt1,
sum(case when yyy then 1 else 0 end) as cnt1
from mygrist_samples.subsample_population

Related

How to correctly display in class data from joined sql tables?

I've started to learn SQL, I'd appreciate some insight and help on the below issue. My task is to: write a query in SQL workbench which returns names and surnames of users with more than 2 posts written (the query copied below). This part seems to work fine.
Then display in test class in a loop names and surnames of users that have published at least 2 posts.
How to write a code that creates that query in the test class? Basically I get syntax error and I'm not sure how it should look like("Column 'POSTS_NUMBERS' not found.").
(then another part of exercise follows - add posts and then check by assertion if the actual number of records in the data base is the same as result of the query)
SELECT USERS.FIRSTNAME, USERS.LASTNAME, USERS.ID, COUNT(*) AS POSTS_NUMBER
FROM USERS
JOIN POSTS ON USERS.ID = POSTS.USER_ID
GROUP BY POSTS.USER_ID
HAVING COUNT(*) >= 2;
#Test
public void testSelectUsersAndPosts() throws SQLException {
//given
DbManager dbManager = DbManager.getInstance();
String countQuery = "SELECT COUNT(*) FROM USERS"; //IS THIS PART CORRECT?
Statement statement = dbManager.getConnection().createStatement();
ResultSet rs = statement.executeQuery(countQuery);
int count = 0;
while (rs.next()) {
System.out.println(rs.getInt("POSTS_NUMBERS") + ", " +
rs.getString("FIRSTNAME") + ", " +
rs.getString("LASTNAME"));
}
String sql = "INSERT INTO POSTS(USER_ID, BODY) VALUES ('3', 'I am Mark')";
statement.executeUpdate(sql);
sql = "INSERT INTO POSTS(USER_ID, BODY) VALUES ('3', 'hey!')";
statement.executeUpdate(sql);
//when
String sqlQuery = "SELECT * FROM USERS";
statement = dbManager.getConnection().createStatement();
rs = statement.executeQuery(sqlQuery);
//then
int counter = 0;
while (rs.next()) {
System.out.println(rs.getInt("USERS.ID") + ", " +
rs.getString("FIRSTNAME") + ", " +
rs.getString("LASTNAME"));
counter++;
int expected = count + 1;
Assert.assertEquals(expected, counter);
rs.close();
statement.close();
}
}

Error catching mysql statement in java

Hello so i'm trying to code my own type of error catching on a sql statement. On my method add order i want to add some way of stopping someone from selling a product which has no stock. My code below does not yet do that. I can add orders and update the stock amount but i haven't figured out a way of adding an if statement that works.
#FXML
public void AddOrder(ActionEvent event) {
String orderID = orderBox.getText();
String customerID = customerBox.getText();
String productID = productBox.getText();
String amount = amountBox.getText();
// String cost = costBox.getText();
String date = dateBox.getText();
PreparedStatement sample;
dc = new Database();
try {
c = dc.Connect();
sample = c.prepareStatement("Select stockAmount from inventory WHERE productID = ?");
ResultSet rs = sample.executeQuery();
while (rs.next()) {
Integer amount2 = rs.getInt("Amount");
if (amount2 <= 0) {
System.out.println("No stock exists");
} else {
query = c.prepareStatement(
"INSERT INTO ordertable (orderID,customerID,productID,Amount,Date)VALUES(?,?,?,?,?)");
update = c.prepareStatement("UPDATE inventory set stockAmount = stockAmount-? WHERE productID =?");
update.setString(1, amount);
update.setString(2, productID);
update.execute();
query.setString(1, orderID);
query.setString(2, customerID);
query.setString(3, productID);
query.setString(4, amount);
// query.setString(5, cost);
query.setString(5, date);
query.executeUpdate();
// update.executeUpdate();
Alert confirmation = new Alert(Alert.AlertType.CONFIRMATION, "Saved");
// closeConfirmation.showMessageDialog(this, "Saved");
confirmation.show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
orderBox.clear();
customerBox.clear();
productBox.clear();
amountBox.clear();
dateBox.clear();
loadDataFromDatabase(event);
}
Below is the error i'm getting
java.sql.SQLException: No value specified for parameter 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
at
If you are just having trouble because of that exception, check these lines:
sample = c.prepareStatement("Select stockAmount from inventory WHERE productID = ?");
ResultSet rs = sample.executeQuery();
The query is defined to accept a parameter for productID, but you haven't given it a value prior to executing the statement. You'll need to change the query so that it doesn't require a parameter or assign a value to the parameter, like this:
sample = c.prepareStatement("Select stockAmount from inventory WHERE productID = ?");
sample.setString(1, productID);
ResultSet rs = sample.executeQuery();

retrieving every attribute of every column from every row of a table mysql java

So far I know that it's possible to select the nth row from a table using the following code SELECT * FROM table ORDER BY column_name LIMIT n-1,1 ; In the following code I am trying to retrieve every attribute of every column from every row of a table named responsable which has the following columns :id,name,surname,mail,password. id is an integer while the other columns' type is string
java.sql.Connection connection = null;
int rowCount;
try {connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/database_name","root","");
Statement stmt = null;
ResultSet result = null;
ResultSet rs = null;
rs = stmt.executeQuery("SELECT COUNT(*) FROM responsable");
rowCount = rs.getInt(1);
if(rowCount!=0)
{
for(int i=0;i<rowCount;i++)
{result= stmt.executeQuery("SELECT * FROM responsable ORDER BY id LIMIT"+i+",1");
System.out.put(result.getInt(1));
System.out.put(result.getString(2));
System.out.put(result.getString(3));
System.out.put(result.getString(4));
System.out.put(result.getString(5));}
}
}catch (Exception ex) {
out.println("Unable to connect to database");
}
I am trying to execute this code but I am getting no result.
Any help would be appreciated.
Your stmt variable is null. You need to create the statement first.
Statement stmt = connection.createStatement();
Also, you need to call next() to retrieve the next row from your resultset.
E.g.
if (rs.next()) {
rowCount = rs.getInt(1);
}
....
if (result.next()) {
System.out.put(result.getInt(1));
System.out.put(result.getString(2));
System.out.put(result.getString(3));
System.out.put(result.getString(4));
System.out.put(result.getString(5));
}

Displaying altered mysql table contents in JTable in java using Vector

I have a mysql table that stores the log of Wireless sensor simulation results. It stores node id of each sensor node, energy of each node and and status of each sensor i.e, whether it is in sending state or recieving state etc. Now I want to create a JTable which displays 5 fileds for each row which are:
NodeId , energy Left, No. Of Packets Sent , No. Of Packets Recieved, No. Of Packets Corrupted.
I am using following queries:
SELECT COUNT(*) FROM node WHERE nodeid='i' AND stetus='sending'
SELECT COUNT(*) FROM node WHERE nodeid='i' AND stetus='corrupted'
SELECT COUNT(*) FROM node WHERE nodeid='i' AND stetus='recieved'
SELECT MIN(energi) FROM node WHERE nodeid='i'
To get Fields for JTable contents.
Below is the Code That I have written: Please help me to resolve this.
I am not able to display JTable.
import java.util.Vector.*;
import java.sql.*;
JFrame f = new JFrame();
f.setSize(800,800);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Connection Db=null;
ResultSet Results,res,rest,re;
String stetus;
Vector data = new Vector();
Vector row = new Vector(50);
JPanel p = new JPanel();
Vector<String> columnNames = new Vector<String>();
double energi,nodeid,en;
String url= "jdbc:mysql://localhost:3306/prowler";
String username="root";
String password = "not telling you";
try {
Class.forName("com.mysql.jdbc.Driver");
Db= DriverManager.getConnection(url,username,password);
}
catch(ClassNotFoundException cnf) {
System.err.println("Unable to load JDBC bridge" + cnf);
System.exit(1);
}
catch(SQLException se) {
System.err.println("Cannot connect to database" + se);
System.exit(2);
}
int num = Integer.parseInt(name.getSelectedText());
for(int i=1;i<=num;i++) {
row.addElement(i);
try {
Statement st = Db.createStatement();
Results = st.executeQuery("SELECT COUNT(*) FROM node WHERE nodeid='i' AND stetus='sending'");
row.addElement(Results.getObject(1));
}
catch(SQLException se) {
System.out.println("Query Not Executed" + se);
}
try {
Statement st = Db.createStatement();
res = st.executeQuery("SELECT COUNT(*) FROM node WHERE nodeid='i' AND stetus='corrupted'");
row.addElement(res.getObject(1));
}
catch(SQLException se) {
System.out.println("Query Not Executed" + se);
}
try {
Statement st = Db.createStatement();
rest = st.executeQuery("SELECT COUNT(*) FROM node WHERE nodeid='i' AND stetus='recieved'");
row.addElement(rest.getObject(1));
}
catch(SQLException se) {
System.out.println("Query Not Executed" + se);
}
try {
Statement st = Db.createStatement();
re = st.executeQuery("SELECT MIN(energi) FROM node WHERE nodeid='i'");
row.addElement(re.getObject(1));
}
catch(SQLException se) {
System.out.println("Query Not Executed" + se);
}
data.addElement(row);
}
columnNames.add("Node Id");
columnNames.add("Packets Sent");
columnNames.add("Packets Corrupted");
columnNames.add("Packets Recieved");
columnNames.add("Energy Left");
JTable table = new JTable(data,columnNames);
JScrollPane jsp = new JScrollPane(table);
p.add(jsp);
f.add(p);
Well if I get you it's fairly simple, something like
Select nodeid,
Count(case stetus when 'sending' then 1 else null end) as Sent,
Count(case stetus when 'received' then 1 else null end) as Received,
Count(case stetus when 'corrupted' then 1 else null end) as Corrupted,
Min(energi) as remaining
From Node Group By NodeId
I think
The case manouver inside count is a sneaky trick. Count(SomeColumnName) will skip nulls, but you can count an expression, so you bash one together, that's null when you don't want it in the count.

Servlets/JSP - Unable to access database on SOAP webservice

I am trying to create a simple little webservice on a glassfish server backed by a mysql server on my netbeans
Its designed to be a very simple currency conversion service
Here is what its supposed to do
It takes an amount of money (Always in GBp) as an INT and a currency to convert it in as a string.
The service then looks up that currency from my database table to get the conversion rate with a query like
select * from exchange.rates where currency = string
Then it performs the simple calculation to convert the money into the currency and returns the amount
The problem is that i have no clue how to call that conversion rate from my mysql server, i tried and tried but nothing happens
i just keep getting the same amount i entered in.
I tried entering euro and 10
I set the rate for that in my database but i just got 10 back out when i tested the webservice
/**
* Web service operation
*/
#WebMethod(operationName = "convert")
public int convert(#WebParam(name = "currency") String currency, #WebParam(name = "amount") int amount) {
int newamount = 0;
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection("jdbc:mysql://localhost:3306/exhange",
"root", "25587");
PreparedStatement st =
con.prepareStatement("select * from rates where currency = '" + currency+"'");
ResultSet rs = null;
rs = st.executeQuery();
rs.first();
newamount =rs.getInt("conversion") * amount;
return newamount;
} catch (Exception e) {
System.out.println("error");
}
return amount;
}
Whe you use prepared statemen you need to pass the parameter explicitly:
PreparedStatement st = con.prepareStatement("select * from rates where currency = ?");
st.setString(1,currency) //Check this
ResultSet rs = st.executeQuery();
// If you are sure that is only one row then you nee to do
String columnX = null;
if (rs.next() != null) {
columnX = rs.getString(1); //Where 1 is the first column
}