ALL query in Ecto - postgresql

I need to translate the following SQL to Ecto Query DSL.
SELECT otc.*
FROM users u
INNER JOIN one_time_codes otc ON u.id = otc.user_id
LEFT OUTER JOIN one_time_code_invalidations otci ON otci.one_time_code_id = otc.id
WHERE u.id = 3 AND
otc.code = 482693 AND
otci.inserted_at IS NULL AND
otc.inserted_at > all(SELECT otc.inserted_at
FROM one_time_codes otc2
WHERE otc2.user_id = 3) AND
otc.inserted_at > (now() - '180 seconds'::interval);
In the third AND statement of WHERE clause, notice there is an ALL query. Ecto seems to not have corresponding function in Ecto.Query.API.
How to apply such aggregate? What is the correct way to implement this, though it could be implemented by having a lookup on debug logs of the Ecto, do you have another idea (or suggestion)?
Thank you.

Ecto does not allow subqueries in expressions, and you're right that there's no all in Ecto's Query API, but you can use fragment like this:
where: ...
and otc.inserted_at > fragment("all(SELECT otc.inserted_at FROM one_time_codes otc2 WHERE otc2.user_id = ?", 3)
and ...

Related

Update PgSQL Self JOIN With Custom Values

I'm trying to use UPDATE SELF JOIN and could not seem to get the correct SQL query.
Before the query, I execute this SQL query to get the values:
SELECT DISTINCT ON (purpose) purpose FROM user_assigned_customer
sales_manager
main_contact
representative
administrator
By the time I run this query, it overwrites all the purpose columns:
UPDATE user_assigned_customer SET purpose = (
SELECT 'main_supervisor' AS purpose FROM user_assigned_customer AS assigned_user
LEFT JOIN app_user ON app_user.id = assigned_user.app_user_id
WHERE app_user.role = 'supervisor'
AND user_assigned_customer.purpose IS NULL
AND assigned_user.id = user_assigned_customer.id
)
The purpose column is now only showing when running the first query:
main_supervisor
Wondering if there is a way to query to update SQL Self JOIN with a custom value.
I think I got it with a help of a friend.
UPDATE user_assigned_customer SET purpose = 'main_supervisor'
FROM user_assigned_customer AS assigned_user
LEFT JOIN app_user ON app_user.id = assigned_user.app_user_id
WHERE app_user.role = 'supervisor'
AND user_assigned_customer.purpose IS NULL
AND assigned_user.id = user_assigned_customer.id

Issue with JPA statement "translation"

I have a JPA statement which is like this
select p from Proposal p where p.creationTime > :startDate AND p.creationTime < :stopDate AND ((p.owner = :owner) OR (:member MEMBER OF p.sharedWithTeam.members)) ORDER BY p.creationTime DESC
But it never generates any result. I use EclipseLink.
After digging a bit into the generated SQL, I found out that it translates the query into something that can never be true!
SELECT XXX FROM userteam_users t3, USERTEAM t2, USERS t1, PROPOSAL t0 WHERE ((((t0.CREATIONTIME > ?) AND (t0.CREATIONTIME < ?)) AND ((t0.OWNER_username = ?) OR (? = t1.username))) AND ((t2.ID = t0.SHAREDWITHTEAM_ID) AND ((t3.teams_ID = t2.ID) AND (t1.username = t3.members_username)))) ORDER BY t0.CREATIONTIME DESC LIMIT ? OFFSET ?
(I only included the from and where clause to make it shorter...)
I can't see what is wrong with my JPQL query. Could it be my use of "OR"? or my "bold" use of the member of condition?
EDIT: in fact, the statement can be true, I misread it. BUT I have proposals with NO shared user team, so the first condition is always false in this case, and it should be true (in my view)
Thanks!

Need help in creating CriteriaQuery

First of all, I would like to know if it is possible to do?
Below is my query and I am trying to build using criteria.
SELECT CONCAT('record-', rl.record_id) AS tempId,
'sloka' AS type,
rl.record_id AS recordId,
rl.title AS title,
rl.locale as locale,
rl.intro AS intro,
rl.title AS localetitle,
NULL AS audioUrl,
lp.name AS byName,
lp.person_id AS byId,
lp.name AS onName,
lp.person_id AS onId
FROM record_locale rl
LEFT JOIN record r ON rl.record_id = r.record_id
LEFT JOIN locale_person lp ON r.written_on = lp.person_id
WHERE rl.title LIKE :title
AND rl.locale = :locale
AND lp.locale = :locale
UNION
SELECT CONCAT('lyric-', s.song_id) AS tempId,
'bhajan' AS type,
s.song_id AS recordId,
s.title,
l.locale as locale,
NULL AS intro,
l.title AS localetitle,
s.audio_url AS audioUrl,
lpb.name AS byName,
lpb.person_id AS byId,
lpo.name AS onName,
lpo.person_id AS onId
FROM song s
LEFT JOIN locale_person lpb
ON (s.written_by = lpb.person_id AND lpb.locale = :locale)
LEFT JOIN locale_person lpo
ON (s.written_on = lpo.person_id AND lpo.locale = lpb.locale)
INNER JOIN lyric l
ON (l.locale = lpb.locale AND l.song_id = s.song_id)
WHERE s.title LIKE :title AND s.approved_by IS NOT NULL
ORDER BY localeTitle ASC
// END
Based on few conditions, I might need to have union of both queries or just individual query without union.
Converting the SQL to JPQL is usually a good first step, as we can't quite tell what these tables map to, or what you are expecting to get back. If it is possible to do in JPQL, it should be possible with a criteria query. Except in this case: JPA/JPQL does not have the union operator so it won't work in straight JPA, but some providers such as EclipseLink have support. See:
UNION to JPA Query
and
http://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/j_union.htm

Linq to Entities nested subqueries

I am fairly new to linq and am having a problem translating the following sql to linq:
select
c3.COURSE, c3.DESCR
from
(select c.courseprefix, MAX(c.coursesuffix) [coursesuffix]
from
(select distinct SUBSTRING(course,1,3)[courseprefix], RIGHT(course, LEN(course) - 3) [coursesuffix]
from PsCourses where LEN(course) >= 3 ) c
group by c.courseprefix
) c2 inner join PsCourses c3 on (c2.courseprefix + c2.coursesuffix) = c3.COURSE
where
c3.COURSE_STATUS = 'A'
order by
c3.course
Well, you can use http://www.sqltolinq.com/downloads
or you can make a IQueryable, but in my personal criteria the complex queries I prefer to write in native sql

Forming JPQL query from native SQL query for multiple views with CASE condition and join statements

Kindly helping in converting native query ti JPQL query for multiple views with CASE condition and join statements.Table c1 and c3 are views. I am trying the get the current and pending information from c1.
Please find the query mentioned below
SELECT c3.eqip_id AS EQIP_ID,
CASE WHEN c1.inst_ts IS NULL OR c1.sent_ts > c1.inst_ts THEN c1.ver_nm END AS PEND,
CASE WHEN c1.sent_ts IS NULL OR c1.sent_ts > c1.inst_ts THEN c1.ver_nm END AS CURRENT,
c1.trm_ver_hist_id AS TRM_VER_HIST_ID
FROM trm_ver_hist_vw c1
JOIN(SELECT Max(trm_ver_hist_id) AS TRM_VER_HIST_ID, dvc_id, status
FROM trm_ver_hist_vw
WHERE ver_typ_id = 1 AND status IN( 'C', 'P' )
GROUP BY dvc_id, status) c2
ON c1.trm_ver_hist_id = c2.trm_ver_hist_id
JOIN trm_dtl_vw c3 ON c1.dvc_id = c3.trm_id
WHERE c3.co_actv_ind = 'Y' AND c3.mach_hdwr_asscn_ind = 'Y' AND pin = 'ABC'
Can anyone please help me to make this query in JPA/JPQL?
It seems very complex and data specific. I would recommend using a native SQL query.
The JPA spec does not allow selects in the FROM clause, although EclipseLink does have some support for this.
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Sub-selects_in_FROM_clause