Convert a SQL query in Java Persistence Query Language (JPQL) - sql

I'm having a little problem to convert this SQL query to JPQL:
select max(datePurchase) from purchases where userId = id and date_trunc('day',datePurchase)
in (select distinct (date_trunc('day',datePurchase)) as day from purchases where userId = id and datePurchase < initialDate and datePurchase > finalDate) group by date_trunc('day',datePurchase)
This sql is working well, that returns de last purchase per day made from a user. I tried to do the same, in JPQL:
Query query = em.createQuery("SELECT u MAX(u.datePurchase) FROM Purchases u WHERE u.userId.id = :id AND FUNC('day',u.datePurchase)" +
"IN (SELECT DISTINCT (FUNC('day',u.datePurchase)) AS day FROM Purchases WHERE u.userId.id = :id AND u.datePurchase < :finalDate AND u.datePurchase > :inicialDate) GROUP BY FUNC('day',u.datePurchase)");
query.setParameter("id", idUsuario);
query.setParameter("dataInicial", dataInicial);
query.setParameter("dataFinal", dataFinal);
List<MovSaldo> saldos = (List<MovSaldo>) query.getResultList();
em.getTransaction().commit();
The errors are:
"The IN expression does not have a valid expression." "An identification variable must be provided for a range variable declaration."
Probably is not something very difficult, but i have already spent a little frustrating time in it. Can someone please help me?

Although the answer is probably late for you I still posted it because it might help someone in the future.
In the nested select you have to put an identifier for the entity you are working with: FROM Purchases p and update things like (FUNC('day',u.datePurchase)) to (FUNC('day',p.datePurchase))
Best!

Related

Using SQL query - How to identify the attribute's that a OIM request has updated + OIM 11g R2 PS3

We extend contractor term date in OIM to 80 days but some times it gets extended by admins/managers more than 80 days. When it gets extended, OIM creates a request id. Now, we would like to know all the users who term date is more than 80 days from the day(request creation date) they got extended.
Is there a way to get the details of the users and the request creation date that happened on termination date attribute in a SQL query so that we can create a BI report.
As i have a requestid which was created yesterday i am using it for developing the query. I tried below query by joining usr, request and request_beneficiary tables but it doesn't return anything. Are there any other tables which i need to use to accomplish this use case.
-- Even try with specific requestid req3.request_id=123456
-- Tried with the request id's beneficiary key too.
SELECT
req3.request_key rk,
usr2.usr_login buid,
usr2.usr_status,
req3.request_creation_date,
req3.request_model_name,
to_char(usr2.usr_udf_terminationdate, 'MM-DD-YYYY') AS Terminationdate
FROM
request req3,
request_beneficiary reqb1,
usr usr2
WHERE
req3.request_key = reqb1.request_key
AND beneficiary_key = usr2.usr_key
and usr2.usr_status = 'Active'
AND usr2.usr_emp_type IN ( 'Contractor');
If anyone has done this type of use case. can you please provide your inputs.
Appreciate your inputs and suggestions
Thanks in advance.
I'm sure you've already figure this out, but here is some SQL that should get you to the data you need.
SELECT r.request_key rk,
R.Request_Creation_Date,
Red.Entity_Field_Name,
Red.Entity_Field_Value,
usr_status,
usr_end_date,
usr_udf_terminationdate
FROM request r
INNER JOIN Request_Entities re
ON R.Request_Key = re.request_key
INNER JOIN Request_Entity_data red
ON re.request_entity_key = red.request_entity_key
INNER JOIN usr
ON Re.Entity_Key = usr.usr_key
WHERE request_model_name = 'Modify User Profile';

MS Access 2016 Error: "Multi-level group by not allowed"

i'm stuck at another point in my little Access 2016 Database. My code looks like the following and i know it probably isn't the cleanest solution but i'm kinda new to this and i tried to educate myself and get some help here already.
I'm trying to play around with the reports now a little bit and i am using this test query which returns all entries of two tables joined together.
As far as i could find out I have this one subquery included that returns the prvious day inventory for each record and that is most likely the cause of my error. I found a possible solution with adding SELECT * FROM at the beginning of my code but i get a Syntax error when i do that and i'm not sure how to solve this problem.
here's my code
SELECT Stations.StationName, Product.ProductName, GasInventoryTransactions.TransactionDate, (SELECT TOP 1 Dupe.ActualInventory FROM GasInventory AS Dupe WHERE Dupe.StationID = Stations.StationID AND Dupe.ProductID = Product.ProductID AND Dupe.InventoryDate < GasInventory.InventoryDate ORDER BY Dupe.InventoryDate DESC) AS PreviousDayInventory, GasInventory.ActualInventory, GasInventoryTransactions.GasSales, GasInventoryTransactions.GasDelivery, [PreviousDayInventory]+[GasDelivery]-[GasSales] AS BookBalance, GasInventory.ActualInventory, [ActualInventory]-[BookBalance] AS OverShort
FROM (Stations INNER JOIN (Product INNER JOIN GasInventory ON Product.[ProductID] = GasInventory.[ProductID]) ON Stations.[StationID] = GasInventory.[StationID]) INNER JOIN GasInventoryTransactions ON GasInventory.[InventoryDate] = GasInventoryTransactions.[TransactionDate];
thanks for your help!

Complex SQL postgres query into ActiveRecord notation?

Hoping an ActiveRecord wizard can help me determine if this kind of query can be done with a AR statement, i.e. without executing the raw SQL or diving into Arel?
I'm getting close but can't seem to figure out how to add the subquery in. I'm on Rails 5.1.1.
SELECT s.id as stock_id, s.count, adjustments.count as
adjustment_count, adjustments.reason as adjustment_reason
FROM
(SELECT * FROM stocks WHERE inventory_id = 6) AS s
LEFT JOIN adjustments
ON (s.id = adjustments.stock_id AND adjustments.reason='run_use')
The end result should be all Stock that have inventory id 6 with the extra columns showing what Adjustment was made to them, if they exist.
If I run the RAW SQL in Navicat I get this result, which is what I'm trying to get via ActiveRecord:
This gets me close, but it just produces stock_ids 11 and 10:
Stock.where(inventory:6)
.left_joins(:adjustments)
.where("adjustments.reason = 'run_use'")
One of these should work for you:
Stock.eager_load(:adjustments)
.where("adjustments.reason = ? OR stocks.inventory_id = ?", "run_use", 6)
or
Stock.eager_load(:adjustments)
.where(adjustments: { reason: "run_use" }, inventory_id = 6)
Hm. It seems you're trying to say:
Give me all Stock that belong to Inventory with id = 6 that also have Adjustments with a reason of 'run use'.
How about something like:
Stock.
where(inventory_id: 6).
joins(:adjustments).
where(adjustments: { reason: 'run_use' })
from the Guides

Trouble with integrating COUNT function in SQL query using Oracle

I am trying to self educate myself in SQL in order to better use databases at work. For this purpose I am using Oracle Application Express. This if my first time using the COUNT function and I am having some difficulties integrating it within my query. I have done a great deal of research and read quite a bit of literature but I just can't seem to get it right.
My goal is to display the channel_name and channel_number columns (from the channel table) for each channel along with a count of the number of customers that have that channel as a favorite channel (survey_result column from the survey table). Please see below for code:
SELECT channel.channel_number,
channel.channel_name,
survey.survey_result,
count(SELECT survey.survey_result FROM survey)
From Channel, survey
WHERE survey.channel_number = channel.channel_number
Currently I am getting the error message:
ORA-00936: missing expression.
Try this:
Below query gives you only those channels which have minimum 1 customer.
SELECT C.channel_number, C.channel_name, COUNT(S.survey_result) NoOfCustomers
FROM Channel C
INNER JOIN survey S ON S.channel_number = C.channel_number
GROUP BY C.channel_number, C.channel_name;
And below query gives you all channels whether it has customer or not.
SELECT C.channel_number, C.channel_name, COUNT(S.survey_result) NoOfCustomers
FROM Channel C
LEFT JOIN survey S ON S.channel_number = C.channel_number
GROUP BY C.channel_number, C.channel_name;
Either of these may work for you
SELECT channel.channel_number,
channel.channel_name,
count(survey.survey_result)
From Channel, survey
WHERE survey.channel_number = channel.channel_number
GROUP BY
channel.channel_number,
channel.channel_name
or
SELECT channel.channel_number,
channel.channel_name,
survey.survey_result,
(SELECT count(survey_result) FROM survey)
From Channel, survey
WHERE survey.channel_number = channel.channel_number
count is an aggregate function thus you should have a group by on channel.channel_number and channel.channel_name. then just use count(survey.survey_result) instead of count(SELECT survey.survey_result FROM survey). Madhivanan's and Saharsh Shah's answers look good to me. including this answer to explain why.

SQL count(), trying to count rows from two tables and restrict info displayed

I am setting up a database that has a limit to the amount of people that can register for a course. In my course table I have a Maximum column which holds an int and in my registered table it holds all the registered people for that course. SO my web page should only display course times where the number of registered people in the registered table < maximum allowed in the course table. Heres my current query.
SELECT course.time,COUNT(registered.time),registered.maximum FROM course
JOIN (registered)
ON course.type = 'computing' OR
(registered.type = 'computing' AND course.time = registered.time)
GROUP BY course.time
HAVING COUNT(registered.time) < course.maximum
The problem with this is it counts all the registered people regardless of the course time, so if there is 2 people registered for different times it still counts 2 people registered for each time.
Hope I explained it ok and hope someone can help. Thanks
It is unclear to me why you have registered.maximum and course.maximum. And it would be easier to answer the question if we knew the actual table structure, rather than having to guess based on your code. But here goes:
SELECT course.time, COUNT(registered.time), registered.maximum
FROM course
JOIN registered
ON course.type = registered.type
AND course.time = registered.time
WHERE course.type = 'computing'
GROUP BY course.time, registered.maximum
HAVING COUNT(registered.time) < course.maximum
I also did a group by on registered.maximum, because you will get a syntax error otherwise.
Finally, I changed the join to be on the type, and then added it to the WHERE clause. To me, that always makes more sense, though it may sometimes be slower. From my perspective, the JOIN clause is just for joining, while the WHERE clause is for filtering.
UPDATE: to also get courses with no one registered:
SELECT course.time, COUNT(registered.time), course.maximum
FROM course
LEFT OUTER JOIN registered
ON course.type = registered.type
AND course.time = registered.time
WHERE course.type = 'computing'
GROUP BY course.time, course.maximum
HAVING COUNT(registered.time) < course.maximum