I try to formulate the following PostgreSQL Query into JOOQ:
SELECT * FROM
(SELECT *, row_number() OVER (PARTITION BY propertyid ORDER BY validfrom DESC)
AS rownum FROM propertyvalue WHERE validfrom <= '1978-01-01T00:00:00Z') X
WHERE rownum = 1;
So I want to write a query with a nested query which uses window functions and start with the inner query first. I came that far:
ctx.select(PROPERTYALUE.fields(), DSL.rowNumber().over().
partitionBy(PROPERTYVALUE.propertyid).orderBy(PROPERTYVALUE.validfrom).???)
After the orderBy command, I don't have a DESC option to be used anymore in JOOQ. There are just commands like rangeFollowing or rowsCurrentRow and an inherited command like desc() which returns a SortField-object on which I can't call my required subsequent commands anymore.
So is there any way in JOOQ to formulate my desired SQL query with the DESC order in a window function?
Write this:
DSL.rowNumber()
.over()
.partitionBy(PROPERTYVALUE.propertyid)
.orderBy(PROPERTYVALUE.validfrom.desc()))
Observe the fact that I called desc() on the column validfrom in order to pass the resulting SortField to the orderBy() clause of the window function call.
What you tried to do would have been to order by the window function expression, e.g. in an ORDER BY clause of the SELECT statement. E.g.:
SELECT *
FROM propertyvalue
WHERE validfrom <= '1978-01-01T00:00:00Z'
ORDER BY row_number() OVER (PARTITION BY propertyid ORDER BY validfrom) DESC
Related
I'm trying to use the same query to sort my table columns but when I pass as a parameter the column to ORDER BY, it adds quotes before and after my column name. If you are using ORDER BY parameter, the column name have to be written without being between quotes or MySQL is going to ignore it.
Example or query to execute:
select * from app_user ORDER BY mobile_token ASC LIMIT 0 , 20
This is what hibernate send to MySQL:
select * from app_user ORDER BY 'mobile_token' ASC LIMIT 0 , 20
Java query:
query = JPA.em().createNativeQuery("select * from app_user ORDER BY :column ASC LIMIT :init , :page",AppUser.class);
query.setParameter("column", column);
query.setParameter("init", pageNumber*pageSize);
query.setParameter("page", pageSize);
I could change the NativeQuery by:
"select * from app_user ORDER BY "+column+" ASC LIMIT :init , :page"
but this is going to become my app unsafety.
You can only pass values as parameters to a query. Not column or field names. That would make it impossible for the database to know which columns are actually used in the query, and thus make it impossible to prepare the execution plan.
So your solution using concatenation is the only one. Just make sure the column doesn't come from the user. Or if it comes from the user, that it's a valid column name and that the user is allowed to use it.
I am using netbeans.
I have a table 'incident' with column 'priority' which can hold values priority 1 , priority 2.
I have created a jcombobox with 3 options - select all( to select all the rows) / priority 1(to select rows with priority 1 and so on) / priority 2. Options are passed through prioritybox.getSelected().
I want to know any possible sql statement so that if i select the option 'select all' , all the entries of the table should be selected.
If i choose priority 1
then the statement
select * from incident where priority='"+prioritybox.getSelected()+"';
gets executed correctly i.e. it select the rows which having priority=priority1. But if i select the option 'select all ' then this statement becomes invalid as no such row is there with priority value = select all.I don't want to use if-else . Any other possible solution??
You need to use if clause.
Go with the following code
String strSelect1 = "select * from table";
if(prioritybox.getSelectedItem()!="your option")
{ strSelect1=strSelect1+" where Priority='"+prioritybox.getSelectedItem()+"'"; };
Now keep on adding this if statements for rest of the fields.
For purely SQL you could do:
select * from incident where priority='"+prioritybox.getSelected()+"' OR '"+prioritybox.getSelected()+"' = 'select all';
However it's probably easier to add logic to add the where clause if the option is not select all.
You can pass special character '%' to query which will return all characters for that you need to replace = with like query and you need to set '%' as your 'SelectAll' value, your query can be like this
select * from incident where priority like '"+prioritybox.getSelected()+"';
String query="";
if(!prioritybox.getSelected().toString().equals("select all")){
query="select * from incident where priority='"+prioritybox.getSelected()+"'";
}
else {
query="select * from incident" ;
}
When using a Java PreparedStatement, the question-mark placeholders aren't being detected. It would throw an error "The column index is out of range: 1, number of columns: 0" when invoking statementName.setLong(1, 123). My example is from Postgres 8.4, but the problem occurs before the SQL has a chance to make it to the SQL server.
After comparing against some working prepared statements, I realized that the broken one contained a subquery similar to:
SELECT * FROM (
SELECT DISTINCT (name)
id,
name
FROM MyTable
WHERE id > ?
ORDER BY name) AS Level1
ORDER BY 1
The solution that worked for me was to convert the query to a CTE (Common Table Expression). The revised query looks like this:
WITH Level1 AS (
SELECT DISTINCT (name)
id,
name
FROM MyTable
WHERE id > ?
ORDER BY name)
SELECT *
FROM Level1
ORDER BY 1
In JDBC, the parameter indexes for prepared statements begin at 1 instead of 0.
I need to execute this sql:
select * from
(select nt.*,
rank() over (partition by feld0 order by feld1 desc) as ranking
from (select bla from test) nt)
where ranking < 3
order by 1,2
This sql works fine in my oracle database but in the h2 database which i use sometimes this doesnt work because rank and partition are not defined.
So i need to transform this sql so that it works in h2 and oracle.
I want to use java to execute this sql. So is it possible to split this sql into different sqls without rank and partition? And then to handle it with java?
If feld1 is unique within feld0 partitions, you could:
select *
, (
select count(*)
from YourTable yt2
where yt2.feld0 = yt1.feld0 -- Same partition
and yt2.feld1 <= yt1.feld1 -- Lower or equal rank
) as ranking
from YourTable yt1
I've got a query that works fine when I run it in SQL Developer, but returns an empty result set when run as a prepared statement. I'm not sure if my query is formatted incorrectly, or if it's something else (which I'll leave for another question entirely).
So here is my query. I've stripped stuff out in order to capture the format of it, and not the business logic. The table has three columns: type, key, and value.
SELECT a.key id, a.value name
FROM
(SELECT * FROM sometable WHERE type='A') a,
(SELECT * FROM sometable WHERE type='B') b,
(SELECT * FROM sometable WHERE type='C') c,
(SELECT * FROM sometable WHERE type='D') d
WHERE a.value = b.key
AND a.value = c.key
AND a.value = d.key
Essentially, should this execute correctly in a prepared statement?
Are you seeing any errors?
The query as is can be run as a Statement since it is a static SQL.