This one is odd...
I have an hql query that ignore the GOUP BY if ORDER BY is included.
it will perform the query without the group by,
but if I remove the order by it will work fine
list = getSession().createQuery(
"SELECT
Brand.name as Brand_name
, Brand.url as Brand_url
, Brand.email as Brand_email
, Brand.brandId as Brand_brandId
, Brand.description as Brand_description
FROM com.affiliates.hibernate.Brand Brand
INNER JOIN Brand.users as users
WHERE 1=1
AND users.userId>'0'
order by Brand.email ASC
group by brandId"//this one will be ignored because of the order by
).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
sql generated:
select
brand0_.NAME as col_0_0_,
brand0_.URL as col_1_0_,
brand0_.EMAIL as col_2_0_,
brand0_.DESCRIPTION as col_3_0_
from
BRAND brand0_
inner join
USERS_BRANDS users1_
on brand0_.BRAND_ID=users1_.BRAND_ID
inner join
USER user2_
on users1_.USER_ID=user2_.USER_ID
where
1=1
and user2_.USER_ID>'0'
order by
brand0_.EMAIL ASC limit ?
First, notice that BRAND.BRAND_ID has been drop from the column projections in the SQL. This is probably related to the group by being dropped as well.
Second, notice there are no aggregate functions defined in the query. Group only works on aggregations. Try adding an aggregate function, such as max, to all of the columns. This might be the cause of the problem
Last, try fully qualifying brandId in the HQL to eliminate any confusion:
group by Brand.brandId
You should apply orderby after groupby but you have written as
order by Brand.email ASC
group by brandId"//this one will be ignored because of the order by
).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
But Change to:
group by brandId"//this one will be ignored because of the order by
).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
order by Brand.email ASC
Then it will work
Related
I have two queries that I'm trying to join together.
In first_query TABLE2.PROCESS_ID, every PROCESS_ID is unique in that table. In second_query though there are several PROCESS_ID's with the same number in TABLE3, so I think I have to do a one-to-many join. The join_query I have is giving me an error ORA-00933: SQL command not properly ended which I'm assuming has something to do with the one-to-many relationship with the JOIN.
I'm not really sure how to resolve this. Any help would be much appreciated!
first_query = """
SELECT TABLE1.RULE_ID, TABLE2.STATUS, TABLE2.ERROR_MESSAGE, TABLE2.PROCESS_ID
FROM TABLE2 LEFT JOIN
TABLE1
ON TABLE1.RULE_ID = TABLE2.RULE_ID
WHERE TABLE1.RULE_NAME IN ('TEST1', 'TEST2')
"""
second_query = """
SELECT RECORDS_PROCESSED, PROCESS_ID, STATUS
FROM TABLE3
"""
join_query = """
SELECT RULE_ID, STATUS, ERROR_MESSAGE, PROCESS_ID
FROM (first_query) as query_1
INNER JOIN (second_query) as query_2
ON query_1.PROCESS_ID = query_2.PROCESS_ID
GROUP BY PROCESS_ID desc
"""
You can not select 4 columns and group by only one of them unles you include selected columns as part of aggregation fucntion(like max(), sum(),...). One of the options is this:
SELECT query_1.RULE_ID --1
, query_2.STATUS --2
, query_1.ERROR_MESSAGE --3
, query_1.PROCESS_ID --4
FROM (SELECT TABLE1.RULE_ID
, TABLE2.STATUS
, TABLE2.ERROR_MESSAGE
, TABLE2.PROCESS_ID
FROM TABLE2
LEFT JOIN TABLE1
ON TABLE1.RULE_ID = TABLE2.RULE_ID
WHERE TABLE1.RULE_NAME IN ('TEST1', 'TEST2')) query_1
INNER JOIN (SELECT RECORDS_PROCESSED
, PROCESS_ID
, STATUS
FROM TABLE3) query_2
ON query_1.PROCESS_ID = query_2.PROCESS_ID
GROUP BY query_1.RULE_ID
, query_2.STATUS
, query_1.ERROR_MESSAGE
, query_1.PROCESS_ID
Also please do consider using aliases like this(in your first query):
SELECT T1.RULE_ID
, T2.STATUS
, T2.ERROR_MESSAGE
, T2.PROCESS_ID
FROM TABLE2 T2
LEFT JOIN TABLE1 T1 ON T1.RULE_ID = T2.RULE_ID
WHERE T1.RULE_NAME IN ('TEST1', 'TEST2')
Also, apply the same logic with aliases on your final query or else you will have a different kind of error : "ORA-00918: column ambiguously defined"
Here is a small demo
CTE (i.e. the WITH factoring clause) might help.
WITH first_query
AS (SELECT table1.rule_id,
table2.status,
table2.error_message,
table2.process_id
FROM table2 LEFT JOIN table1 ON table1.rule_id = table2.rule_id
WHERE table1.rule_name IN ('TEST1', 'TEST2')),
second_query
AS (SELECT records_processed, process_id, status FROM table3)
SELECT a.rule_id,
a.status,
a.error_message,
a.process_id
FROM first_query a INNER JOIN second_query b ON a.process_id = b.process_id
GROUP BY you used is invalid; you can't group results by only one column. If results have to be unique, use select distinct. If you have to use group by, specify all columns returned by select (which leads you back to what distinct does), or see whether some column(s) have to be aggregates - in that case, group by makes sense.
Also, you should always use table aliases. Without them, query is invalid as database engine doesn't know which table those columns (if they share the same name) belong to.
I have an excel file with some data in it (ids) and these id's have more than one record in the database. There are around 400 ids I have and I need to get the latest record for every id. I don't want to do it one by one. I tried using IN clause but it didn't work.
Select *
from myTable with (nolock)
where submission_number IN ('02597', '69875')
order by timestame DESC;
Above query doesn't work what I want. Can some please help/guide?
Thanks
I would do this using apply:
select t.*
from (values ('02597'), ('69875')) v(submission_number) cross apply
(select top (1) t.*
from mytable t
where t.submission_number = v.submission_number
order by t.timestamp desc
) t;
One nice feature is that you can use outer apply, which will return a row in the result set even when there is no match in your table.
Another method that doesn't use a subquery is;
select top (1) with ties t.*
from myTable t
where submission_number in ('02597', '69875')
order by row_number() over (partition by submission_number order by timestame desc);
You can use row_number for that:
select *
from (
select *, row_number() over (partition by submission_number order by timestame desc) rn
from yourtable
) t
where rn = 1
This will return a single record for each submission_number. If you only want the 2 in your in clause, you can add that back as where criteria.
How would represent the following Oracle SQL in Hibernate HQL.
select table_num
, room_id
, min(event_type) keep(dense_rank first order by changed_on desc)
from room_history
group by table_num, room_id;
The idea behind the query is to order the table "room_history" by "changed_on" datetime column and then group it by "table_num" and "room_id" pairs whilest keeping the first "event_type" for each group. The mentioned query works for Oracle but I have trouble converting it into HQL.
Purpose is to get the latest "event_type" for "table_num" and "room_id" pair.
It seems this is not achievable
I ended up converting the following SQL query instead. It is not perfect but it does the job for my purposes.
select table_num, event_type et from room_history where id in (select max(id) from privacy_history group by msisdn);
I was able to do this assumptions since when for this table always a.id > b.id then also a.changed_on> b.changed_on.
Excuse me for anking again about this issue but I need to have a JPA query for this:
select username, count(*)
from Records
group by username
order by count(*) desc
limit 1
I thought about smth like:
select r.username,count(*) from Records r order by r.username desc
and then to call
getResultList().get(0)
but I am allowed to write only:
select r from Records r order by r.username desc
and in this case I do not know how to get what I need.
Does anyone have any idea?
The SQL query has a group by, and orders by count. The JPA query doesn't have any group by and orders by user name. So I don't see how they could return the same thing.
The equivalent JPQL query is
select r.username, count(r.id)
from Record r
group by r.username
order by count(r.id) desc
If you call setMaxResults(1) on the Query object, the limit clause will be added to the generated SQL query, making it completely equivalent.
I would like to execute this SQL request in QueryDSL JPA
SELECT authorizationitem.*
FROM authorizationitem
INNER JOIN
(
SELECT `authorize`
FROM authorizationitem
GROUP BY `authorize`
HAVING COUNT(*)>1
) a2
ON authorizationitem.`authorize` = a2.`authorize`;
in order to find duplicated row in a table, i should execute this request. But with QueryDSL, i cannot find the way to write this.
It seems QueryDSL does not allow subQuery in Inner Join :s
Any suggestion?
Thanks
regards,
You can't express this with HQL/JPQL, so you will need to expess this with SQL. Querydsl JPA provides the possibility to express both JPQL and SQL queries through its API.
You can try using a subquery in the WHERE clause, but it will probably be less efficient than the subquery in the FROM clause. Make sure there is an index on authorizationitem.authorize to optimize the joins and the GROUP BY.
SELECT authorizationitem.*
FROM authorizationitem
WHERE EXISTS (
SELECT `authorize`
FROM authorizationitem2
WHERE authorizationitem2.authorize = authorizationitem.authorize
GROUP BY `authorize`
HAVING COUNT(*)>1
);
or
SELECT authorizationitem.*
FROM authorizationitem
WHERE (
SELECT count(*)
FROM authorizationitem2
WHERE authorizationitem2.authorize = authorizationitem.authorize
GROUP BY `authorize`
) > 1;