Dynamic pivot in SQL Server database - java

I'm writing a query where there is pivot table that has to generated. Right now below is my code.
select *
from
(select [case owner], [time taken(minutes)] from StatusTable) as pivotdata
pivot(
sum([time taken(minutes)])
for [CASE OWNER] in
("XXX", "AAA", "BBB")
) as pivoting
But instead of giving the rows in for-in, I need to get this dynamically, I've seen a query here SQL Server dynamic PIVOT query? And modified my query to be
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME([case owner])
FROM StatusTable c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'select *
from
(select [case owner], [time taken(minutes)] from StatusTable) as pivotdata
pivot(
sum([time taken(minutes)])
for [CASE OWNER] in
('+#cols+')
) as pivoting'
execute(#query)
And this is working fine, but the problem is that I've to use this query in my JDBC program. And without using execute(#query), it is not running in my SQL Server. Can I make this query similar to the first query, so that I can use the same in my program?

Microsoft's JDBC Driver for SQL Server (mssql-jdbc) supports the execution of an anonymous code block (multiple SQL statements) so we can just execute the same SQL code, including the EXECUTE(...) at the end:
String sql = " "
+ "SET NOCOUNT ON; "
+ "DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX); "
+ " "
+ "SET #cols = "
+ " STUFF( "
+ " ( "
+ " SELECT distinct ',' + QUOTENAME([case owner]) "
+ " FROM StatusTable c "
+ " FOR XML PATH(''), TYPE "
+ " ).value('.', 'NVARCHAR(MAX)'), "
+ " 1, "
+ " 1, "
+ " ''); "
+ " "
+ "set #query = 'select * "
+ "from "
+ "( "
+ " select [case owner], [time taken(minutes)] from StatusTable "
+ ") as pivotdata "
+ "pivot( "
+ " sum([time taken(minutes)]) for [CASE OWNER] in ('+#cols+') "
+ ") as pivoting'; "
+" "
+ "execute(#query); ";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
// print column headings
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.printf("%5s", rsmd.getColumnLabel(i));
}
System.out.println();
rs.next();
// print column values
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.printf("%5s", rs.getString(i));
}
System.out.println();
/* console output:
AAA BBB XXX
2 13 1
*/

Related

SQL Query - FindCostumerWithHighestBill

I am try to find the costumer with the highest bill using this sql that I wrote , but apparently I run into this error :
Every derived table must have its own alias
This is what I wrote:
public static void findCustomerWithHighestBill(Connection c) throws SQLException {
String query = "SELECT CustomerID, CustomerName, CITY, sum(sum_all) As 'data'\r\n"
+ "FROM (SELECT *, sum(Price) As 'sum_all'\r\n"
+ " FROM (SELECT *, Customer.NAME AS \"CustomerName\"\r\n"
+ " FROM Transactions\r\n"
+ " INNER JOIN Product ON Product.ID = Transactions.ProductID\r\n"
+ " INNER JOIN Customer ON Customer.ID = Transactions.CustomerID)\r\n"
+ " GROUP BY CustomerID, ProductID\r\n"
+ " ) \r\n"
+ "GROUP BY CustomerID\r\n"
+ "ORDER BY data DESC";
Statement statement = c.createStatement();
ResultSet set = statement.executeQuery(query);
set.next();
System.out.println("CustomerID: " + set.getInt("CustomerID") +
", Name: " + set.getString("CustomerName") + ", City: " +
set.getString("CITY") + ", Bill: " + set.getFloat("data"));
}
Can please somoane help me zith this ?
Coming back ,
It seems that indeed ad most of you says in the comments I should identify my tables first but, apparently I also have miss to avoid the duplicate ID column.
Here goes my new query:
String query = "SELECT CID, CustomerName, City, sum(sum_all) As data" +
" FROM (SELECT *, sum(PPROD) As sum_all" +
" FROM (SELECT Product.ID as PID,Customer.ID as CID,Product.Price as PPROD,City, Customer.NAME AS CustomerName" +
" FROM Transactions" +
" INNER JOIN Product ON Product.ID = Transactions.ProductID" +
" INNER JOIN Customer ON Customer.ID = Transactions.CustomerID) As t2" +
" GROUP BY CID, PID" +
" ) As t1" +
" GROUP BY CID" +
" ORDER BY data DESC;";

Why I keep getting the error : org.postgresql.util.PSQLException: ERROR: syntax error at or near "(" in my jdbc code?

I am trying to write a method in jdbc in order to update some columns in my database (postgresql)
Here is what I have written so far:`
public void showRoomBookings(int clientID) {
Scanner myObj = new Scanner(System.in);
Statement st;
try {
st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet res = st.executeQuery("SELECT rb.\"hotelbookingID\",rb.\"roomID\",rb.\"bookedforpersonID\",rb.checkin,rb.checkout,rb.rate\r\n"
+ "FROM roombooking rb ,hotelbooking hb\r\n"
+ "where rb.\"bookedforpersonID\"=hb.\"bookedbyclientID\"\r\n"
+ "AND hb.\"bookedbyclientID\"="+clientID+"\r\n"
+ "order by rb.\"hotelbookingID\"");
int j=1;
while(res.next()) {
System.out.println(j+")roomID:"+res.getInt(2)
+" bookedforpersonID:"+res.getInt(3)+" checkin:"+res.getDate(4)+" checkout:"+res.getDate(5)
+" rate:"+res.getInt(6));
j++;
}
System.out.println("Enter the number of the room you want to update:");
int answer = myObj.nextInt();
ResultSet res1 = st.executeQuery("Select t2.\"hotelbookingID\",t2.\"roomID\",t2.\"bookedforpersonID\",t2.checkin,t2.checkout,t2.rate\r\n"
+ "From \r\n"
+ "(\r\n"
+ " Select \r\n"
+ " Row_Number() Over (Order By t1.\"hotelbookingID\") As RowNum\r\n"
+ " , *\r\n"
+ " From (\r\n"
+ "SELECT rb.\"hotelbookingID\",rb.\"roomID\",rb.\"bookedforpersonID\",rb.checkin,rb.checkout,rb.rate\r\n"
+ "FROM roombooking rb ,hotelbooking hb\r\n"
+ "where rb.\"bookedforpersonID\"=hb.\"bookedbyclientID\"\r\n"
+ "AND hb.\"bookedbyclientID\"=107\r\n"
+ "order by rb.\"hotelbookingID\"\r\n"
+ " )t1\r\n"
+ ") t2\r\n"
+ "Where RowNum = "+answer);
System.out.println("You chose room: ("+answer+")");
while(res1.next()) {
System.out.println(res1.getInt(1)+" roomID:"+res1.getInt(2)
+" bookedforpersonID:"+res1.getInt(3)+" checkin:"+res1.getDate(4)+" checkout:"+res1.getDate(5)
+" rate:"+res1.getInt(6));
res1.updateInt("rate", 40);
res1.updateRow();
}
res.close();
res1.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
In the first ResultSet res I just project the roombookings bases on the clientID and then with ResultSet res1 I choose one of them. My console looks like this:
The problem here is that when I try to update rate :
res1.updateInt("rate", 40);
res1.updateRow();
I get the following message:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "("
Position: 8 at
postgresql#42.2.20.jre7/org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553)
at
postgresql#42.2.20.jre7/org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2285)
at
postgresql#42.2.20.jre7/org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:130)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgResultSet.updateRow(PgResultSet.java:1445)
at lol.DbApp.showRoomBookingss(DbApp.java:246) at
lol.DbApp.main(DbApp.java:290)
Here is my postgresql final result(the same as the last line from the console above):
EDIT: SQL CODE:
Select
t2."hotelbookingID",
t2."roomID",
t2."bookedforpersonID",
t2.checkin,
t2.checkout,
t2.rate
From(
Select
Row_Number() Over (
Order By
t1."hotelbookingID"
) As RowNum,
*
From
(
SELECT
rb."hotelbookingID",
rb."roomID",
rb."bookedforpersonID",
rb.checkin,
rb.checkout,
rb.rate
FROM
roombooking rb,
hotelbooking hb
WHERE
rb."bookedforpersonID" = hb."bookedbyclientID"
AND hb."bookedbyclientID" = 107
order by
rb."hotelbookingID"
) t1
) t2
Where
RowNum = 3
group by
t2."hotelbookingID",
t2."roomID",
t2."bookedforpersonID",
t2.checkin,
t2.checkout,
t2.rate
Any help would be valuable.

How to write prepared statements for this query?

Hi i have written a join query for my app and its working. My next requirement is to convert that query to prepared statement where I am stuck.
"SELECT * FROM " + TableA.TABLE + " as d LEFT JOIN " + TableB.TABLE + " as c ON d."+ TableA.DAMAGECODE + "=c." + TableB.DAMAGECODE + " AND d."
+ TableA.INDEX + "=c." + TableB.DAMAGECODEINDEX + " AND d."
+ TableA.OBJECTTYPE + "=c." + TableB.OBJECTCLASS + " WHERE d."+ TableA.LEAF + " = '1' AND d." + TableA.OBJECTTYPE + " = ? AND " + "(d."+ TableA.DAMAGECODE + " LIKE ? OR d." + TableA.DAMAGETEXT + " LIKE ?) AND c." + TableB.CONSTRUCTIONSERIES + " = ? ORDER BY " + TableA.DAMAGETEXT;
cursor = db.rawQuery(sql,new String[]{String.valueOf(objectClass),"'%" + query + "%'","'%" + query + "%'",constructionSeries});
When i ran raw query i am getting results ,but when ran the above prepared statements i am getting cursor count always zero
You don't need to add the ' yourself when you pass a String parameters, the PreparedStatement will manage those itself.
"'%" + query + "%'"
For the moment you have condition like
where columnA = "'%somethingToFind%'"
So unless you have a value in columnA like 'somethingToFindInColumnA' (note the quote at the begin and the end of that String). You will never get a result.
Remove those to get something like :
"%" + query + "%"
Full answer :
db.rawQuery(sql,new String[]{String.valueOf(objectClass),"'%" + query + "%'","'%" + query + "%'",constructionSeries});
Become :
db.rawQuery(sql,new String[]{String.valueOf(objectClass),"%" + query + "%","%" + query + "%",constructionSeries});

Unknown column 'ROWNUM' in 'where clause'

I read a lot of topics about this problem but most of them were having problem with some complex (at least for me) code;
I have followed the oracle ROWNUM Pseudocolumn guide but when I write
SELECT * FROM " + tableName + "
WHERE ROWNUM < 12;
I get this error:
Unknown column 'ROWNUM' in 'where clause'
I then tried to do like the solution suggested here Select where row number = rownum
but nothing changes.
My code looks like this:
sql = "SELECT C.* "
+ "FROM ( SELECT * "
+ " FROM " + tableName + " ) C "
+ "WHERE C.ROWNUM < 12;";
resultSet = statement.executeQuery(sql);
You can refer http://www.w3schools.com/sql/sql_top.asp.
ROWNUM is used in Oracle. Assuming you are using MySQL as you have tagged your question to MySQL.
You can change ROWNUM with limit clause
SELECT * FROM " + tableName + "
LIMIT 11;
Use the below
sql = ""
+ "SELECT C.*,ROWNUM as RECNUM "
+ "FROM ( "
+ " SELECT * "
+ " FROM " + tableName + " ) C "
+ "WHERE C.RECNUM < 12;";
resultSet = statement.executeQuery(sql);
Try this it will helpful for ur problem:
select * from (select * from " + tableName + ") "WHERE C.ROWNUM < 12;
Try this : [if you use mysql]
sql = ""
+ "SELECT C.* "
+ "FROM ( "
+ " SELECT * "
+ " FROM " + tableName + " ) C "
+ "LIMIT 11;";
resultSet = statement.executeQuery(sql);
For sql server :
SELECT TOP 12 ...

Getting back movie ratings excluding my own

Basically, I have a table called ratings with 3 columns FILM, EMAIL, and RATING in mysql.
I can get back the average rating for all the films, but I must then display the ratings
of the movies that I haven't already rated , so I must only display all the films everybody else rated except me.
String email = Main_Login.accounttext.getText().trim();
statement = (PreparedStatement) con
.prepareStatement(""
+ "SELECT FILM,(film_total_ratings/number_of_ratings) as ratings_rating "
+ "FROM( "
+ "SELECT COUNT(*) as number_of_ratings, FILM, "
+ " SUM(RATING) as film_total_ratings "
+ " FROM ratings GROUP BY film "
+ "ORDER BY rating DESC"
+ ") TMP_Film");
result = (ResultSet) statement.executeQuery();
int i = 0;
while (result.next() && i <= 4) {
i++;
// if (result.getString(1).contains(email)) {
System.out.println((i) + ")" + " " + "[Movies You Might Like]"
+ " " + result.getString(1) + " " + "[Rating]" + " "
+ result.getString(2));
You may try to use CASE to add a column indicating that movie has been rated by the respective email or not. This is not tested but you may get the concept:
statement = (PreparedStatement) con
.prepareStatement(""
+ "SELECT FILM,(film_total_ratings/number_of_ratings) as ratings_rating "
+ "FROM( "
+ "SELECT COUNT(*) as number_of_ratings, FILM, "
+ " SUM(RATING) as film_total_ratings, "
+ " SUM(CASE WHEN EMAIL LIKE '%"+email+"%' THEN 1 ELSE 0 END) as rated"
+ " FROM ratings GROUP BY film HAVING rated=0 "
+ "ORDER BY rating DESC"
+ ") TMP_Film");

Categories