JPA: Condition by subquery as expression - sql

I have a JPA query like:
SELECT u.id, (SELECT u2.status AS selectedPreviousStatus FROM ...)
FROM ...
WHERE u.id IN :ids AND selectedPreviousStatus IN :selectedPreviousStatuses
But I get an exception:
The identification variable 'selectedPreviousStatus' is not defined in the FROM clause
How can I build a condition based on a field I got by an subquery as expression?

Related

Fields that not used in`GROUP BY` is not reachable in HAVING clauses

Fields that not used in GROUP BY are not usable in SELECT but they're usable in WHERE. This makes sense since WHEN comes before GROUP BY but shouldn't HAVING has to be able to access "other" columns of the row.
Example
Below is valid.
select fid, count(*)
from class
inner join faculty using (fid)
group by fid
having every(class.room = 'R128')
But can't do this.
select fid, count(*)
from class
inner join faculty using (fid)
group by fid
having class.room = 'R128' // Changed Line
Error message of above snippet:
RROR: column "class.room" must appear in the GROUP BY clause or be used in an aggregate function
LINE 7: having class.room = 'R128'
^
SQL state: 42803
Character: 86
I didn't fall into XY Problem, I want to know why this is impossible (Question is correct with every() later is wrong in semantics too for the question)
having is used to filter the result of the grouping.
However the room column is neither part of an aggregate nor part of the GROUP BY.
every() is an aggregate function an thus it's allowed in the having clause.
You can only use aggregate functions in a HAVING clause and “every” is an aggregate function

Why Scalar Subquery Expressions in the following queries did not violate rules?

Oracle says scalar subqueries are not valid expressions in the following places:
In WHEN conditions of CASE expressions
In GROUP BY and HAVING clauses
But why the following queries don't give any error.(Don't go to the purpose,I am just trying some random examples)
select case when (select id from employee where id=60)=60 then 1 end if from employee;
select id from employee group by id having (select id from employee where id=60)=60;
Let there be only one id with value 60

How do I correct this query that contains a subquery in db2?

I have a query that i use in db2 as follows:
SELECT DISTINCT(
SELECT
DD.NAME
FROM
DIVISIONTABLE DD
WHERE
DD.DIVISION_ID=ll.DIVISION_ID
fetch first 1 rows only
) AS LASTNAME
-- few more attributes that do not use a subquery as above
FROM
lineTable ll
WHERE
ll.id = 113835
GROUP BY
(ll.attr1, ll.attr2)
The problem is that if i remove the subquery above, the query works fine.
I get this error: DB2 SQL Error: SQLCODE=-119, SQLSTATE=42803, SQLERRMC=DIVISION_ID that states "A COLUMN OR EXPRESSION IN A HAVING CLAUSE IS NOT VALID". But I haven't used a having clause anywhere. So I'm unable to understand this error.

HQL Subquery Problems

I'm getting a HQL error every time I try to run this subquery. This type of query should work in SQL right? How is HQL handling this type of query differently?
SELECT *
FROM Table
WHERE user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
It looks like HQL does not support IN?
I'm getting a error: "Cannot recognize input near 'SELECT'"
In hql if you want to select all fields, you have two ways:
1-You can remove select clause like:
FROM Table
WHERE user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
or
2-If you want to use select clause, you must use an alias:
SELECT t
FROM Table t
WHERE t.user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
It looks like your syntax is incorrect. Try this:
SELECT *
FROM Table
WHERE user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
There is no "*" in HQL. Only alias should be present.
SELECT t
FROM Table t
HQL supports "In".
Also, make sure, the java class field name is "user_Id". You may be using the DB column name here.

Give priority to ORDER BY over a GROUP BY in MySQL without subquery

I have the following query which does what I want, but I suspect it is possible to do this without a subquery:
SELECT *
FROM (SELECT *
FROM 'versions'
ORDER BY 'ID' DESC) AS X
GROUP BY 'program'
What I need is to group by program, but returning the results for the objects in versions with the highest value of "ID".
In my past experience, a query like this should work in MySQL, but for some reason, it's not:
SELECT *
FROM 'versions'
GROUP BY 'program'
ORDER BY MAX('ID') DESC
What I want to do is have MySQL do the ORDER BY first and then the GROUP BY, but it insists on doing the GROUP BY first followed by the ORDER BY. i.e. it is sorting the results of the grouping instead of grouping the results of the ordering.
Of course it is not possible to write
SELECT * FROM 'versions' ORDER BY 'ID' DESC GROUP BY 'program'
Thanks.
By definition, ORDER BY is processed after grouping with GROUP BY. By definition, the conceptual way any SELECT statement is processed is:
Compute the cartesian product of all tables referenced in the FROM clause
Apply the join criteria from the FROM clause to filter the results
Apply the filter criteria in the WHERE clause to further filter the results
Group the results into subsets based on the GROUP BY clause, collapsing the results to a single row for each such subset and computing the values of any aggregate functions -- SUM(), MAX(), AVG(), etc. -- for each such subset. Note that if no GROUP BY clause is specified, the results are treated as if there is a single subset and any aggregate functions apply to the entire results set, collapsing it to a single row.
Filter the now-grouped results based on the HAVING clause.
Sort the results based on the ORDER BY clause.
The only columns allowed in the results set of a SELECT with a GROUP BY clause are, of course,
The columns referenced in the GROUP BY clause
Aggregate functions (such as MAX())
literal/constants
expresssions derived from any of the above.
Only broken SQL implementations allow things like select xxx,yyy,a,b,c FROM foo GROUP BY xxx,yyy — the references to colulmsn a, b and c are meaningless/undefined, given that the individual groups have been collapsed to a single row,
This should do it and work pretty well as long as there is a composite index on (program,id). The subquery should only inspect the very first id for each program branch, and quickly retrieve the required record from the outer query.
select v.*
from
(
select program, MAX(id) id
from versions
group by program
) m
inner join versions v on m.program=v.program and m.id=v.id
SELECT v.*
FROM (
SELECT DISTINCT program
FROM versions
) vd
JOIN versions v
ON v.id =
(
SELECT vi.id
FROM versions vi
WHERE vi.program = vd.program
ORDER BY
vi.program DESC, vi.id DESC
LIMIT 1
)
Create an index on (program, id) for this to work fast.
Regarding your original query:
SELECT * FROM 'versions' GROUP BY 'program' ORDER BY MAX('ID') DESC
This query would not parse in any SQL dialect except MySQL.
It abuses MySQL's ability to return ungrouped and unaggregated expressions from a GROUP BY statement.