Infinite loop when I updated query to add an additional variable - postgresql

I have this query:
with users_having_connected as (
select u.id as user_id,
(a.connected_at is not null) has_connected
from core_user u
join core_profile p on u.id = p.user_id
join core_conversation c on (c.profile1_id = p.id or c.profile2_id = p.id)
join analytics_connection a on c.id = a.conversation_id
group by u.id, (a.connected_at is not null)
)
select u.id as user_id,
date_trunc('month', u.created at time zone 'UTC')::date as month,
p.community_id,
p.organization_id,
p.profile_type_intention,
(p.basic_account_completed and (p.is_mentor or p.is_entrepreneur)) as profile_is_completed,
exists(select 1 from core_message where core_message.sender_id = p.id) as has_sent_a_message,
(EXISTS (SELECT 1 FROM core_message WHERE core_message.receiver_id = p.id)) AS has_received_a_message,
(EXISTS (SELECT 1 FROM core_admin_conversation_w_resp WHERE core_admin_conversation_w_resp.initiator_id = p.id or core_admin_conversation_w_resp.responder_id = p.id)) AS has_one_by_one,
exists(select 1 from users_having_connected where user_id = u.id) as has_two_by_two
from core_user as u
join core_profile p on u.id = p.user_id
where
p.profile_type_intention is not null
Which worked fine until I added this line:
(EXISTS (SELECT 1 FROM core_admin_conversation_w_resp WHERE core_admin_conversation_w_resp.initiator_id = p.id or core_admin_conversation_w_resp.responder_id = p.id)) AS has_one_by_one,
This specific variable add causes this query to infinite loop. What do I need to do to fix it? Am I missing a set of parentheses somewhere?

Related

How do you use group by and having clause in EF with parent/child relationship?

How can I write a linq to entities query that includes a group by and a having clause?
For example in SQL:
SELECT * FROM dbo.tblParent p
INNER JOIN
(
SELECT a.ID
FROM dbo.tblParent a
join dbo.tblChild c ON a.ID = c.FkParentID
WHERE a.ColValue = 167
GROUP BY A.ID
HAVING COUNT(c.ID) = 1
) t ON p.ID = t.ID
I found my own answer.
// this is far from pretty but it works as far as I can tell
Apps = (from x in context.tblParents
join t in (
from p in context.tblParents
join c in context.tblChilds
on p.ID equals c.FkParentID
where p.ColValue == 167
group c.ID by p.ID into grouped
where grouped.Count() == 1
select new { grouped.Key }) on x.ID equals t.Key
select x);

MOODLE - i need a query that returns latest enrolment date in course

this query is not returning correct latest_enrolment date. whenever i enrol a user in course, it doesnot updates enrolment date in database.. can anyone help?
SELECT TRIM(c.id) course_id,TRIM(c.fullname) course_fullname,FROM_UNIXTIME(u.timecreated) as registration ,FROM_UNIXTIME( ra.timemodified ) latest_enrolment_date,COUNT( * ) AS enrol_count
FROM mdl_user u
INNER JOIN mdl_role_assignments ra ON ra.userid = u.id
INNER JOIN mdl_context ct ON ct.id = ra.contextid
INNER JOIN mdl_course c ON c.id = ct.instanceid
INNER JOIN mdl_role r ON r.id = ra.roleid
INNER JOIN mdl_course_categories cc ON cc.id = c.category
WHERE r.id =5 GROUP BY c.id
Something like this
SELECT MAX(ue.timecreated) AS latest_enrolment_date
FROM mdl_enrol e
JOIN mdl_user_enrolments ue ON ue.enrolid = e.id
WHERE e.courseid = xx

Postgres UPDATE statement

I have moved from mysql to psql, but find it hard to get my head around the UPDATE statement using multiple left joins.
How would you rewrite this in Postgres? (I am using postresql 9.4)
update task t
left join project p on t.project_id = p.id
left join client c on t.client_id = c.id
left join user u on t.user_id = u.id
set t.project_name = p.name,
t.client_name = c.name,
t.user_name = u.name;
Any pointer will be welcome.
Here you go:
WITH task_data AS (
SELECT t.id,
p.name AS project_name,
c.name AS client_name,
u.name AS user_name
FROM task t
LEFT JOIN project p ON t.project_id = p.id
LEFT JOIN client c ON t.client_id = c.id
LEFT JOIN "user" u ON t.user_id = u.id
)
UPDATE task t
FROM task_data d
SET
project_name = d.project_name,
client_name = d.client_name,
user_name = d.user_name
WHERE t.id = d.id
I would be curious to see if there is a more efficient way

Grades of each quiz in Moodle

I'm trying to get grades of each question, I have a query but it only return final grade of whole exam, but i want grade of each question, how to get it?
Here is query that i have:
SELECT mdl_grade_items.id AS ItemID,
mdl_course.shortname AS CourseShortname,
mdl_grade_items.itemname AS ItemName,
mdl_grade_items.grademax AS ItemGradeMax,
mdl_grade_items.aggregationcoef AS ItemAggregation,
mdl_grade_grades.finalgrade AS FinalGrade,
mdl_user.username AS StudentID,
mdl_user.id
FROM mdl_grade_items
INNER JOIN mdl_grade_grades
ON mdl_grade_items.id = mdl_grade_grades.itemid
INNER JOIN mdl_role_assignments
ON mdl_grade_grades.userid = mdl_role_assignments.userid
AND mdl_grade_items.courseid = mdl_role_assignments.mdlcourseid
INNER JOIN mdl_course
ON mdl_course.id = mdl_grade_items.courseid
INNER JOIN mdl_user
ON mdl_user.id = mdl_role_assignments.userid
Ok, i found it
SELECT mqa.id,meqi.grade * (select fraction from mdl_question_attempt_steps where
questionattemptid = mqas.questionattemptid and state like 'mangr%' order by id desc limit
1 ) finalgrade,me.course , mqas.userid,u.firstname, u.lastname, mqa.questionsummary,
mqa.responsesummary , meqi.grade
FROM mdl_question_attempts mqa
left JOIN mdl_question_attempt_steps mqas ON mqa.id = mqas.questionattemptid
left JOIN mdl_user u ON mqas.userid = u.id
left JOIN mdl_examm_question_instances meqi ON meqi.question = mqa.questionid
left JOIN mdl_examm me ON meqi.examm = me.id
WHERE me.course= $courseID and userid = $userID

Row_Number () Over Certain Value Rows

SELECT
ROW_NUMBER() OVER (PARTITION BY s.ExitStateTypeId ORDER BY s.InsertDate) AS Number
,x.Id
,p.FirstName
,p.LastName
,p.PN
,t.Name
,s.ExitStateTypeId as [Status]
,g.Name
,x.OrganisationId
,d.Name AS Direction
,d.Id AS DirectionId
,h.Name AS Referal
,h.Id AS HealthOrgTypeId
,s.IssueDate
,s.InsertDate
FROM [DB1].[dbo].[Exits] x
INNER JOIN [DB1].[dbo].[ExitStates] s on x.Id = s.ExitId
INNER JOIN [DB1].[dbo].[HealthOrgTypes] h on x.HealthOrgTypeId = h.Id
INNER JOIN [DB1].[dbo].[Directions] d on x.DirectionId = d.Id
INNER JOIN [DB1].[dbo].[HealthCards] c on x.HealthCardId = c.Id
INNER JOIN [DB2].[pr].[TABLE] p on p.Id = c.TABLEId
INNER JOIN [DB3].[orgs].[Organizations] g on g.Id = x.OrganisationId
INNER JOIN [DB4].[dbo].ExitStateTypes t on t.Id = s.ExitStateTypeId
WHERE s.Id = (SELECT MAX(es.Id) from ExitStates es WHERE es.ExitId=x.Id)
ORDER BY s.InsertDate
This is my query, but what I need is that I want only those rows to be enumerated by ROW_NUMBER which s.ExitStateTypeId is in (4,7), for the other rows it should be -1.
Here's the incorrect query just for getting the idea.
SELECT
ROW_NUMBER() OVER (PARTITION BY s.ExitStateTypeId Where s.ExitStateTypeId IN (4,7)
ORDER BY s.InsertDate) AS Number
,x.Id
,p.FirstName
,p.LastName
,p.PN
,t.Name
,s.ExitStateTypeId as [Status]
,g.Name
,x.OrganisationId
,d.Name AS Direction
,d.Id AS DirectionId
,h.Name AS Referal
,h.Id AS HealthOrgTypeId
,s.IssueDate
,s.InsertDate
FROM [DB1].[dbo].[Exits] x
INNER JOIN [DB1].[dbo].[ExitStates] s on x.Id = s.ExitId
INNER JOIN [DB1].[dbo].[HealthOrgTypes] h on x.HealthOrgTypeId = h.Id
INNER JOIN [DB1].[dbo].[Directions] d on x.DirectionId = d.Id
INNER JOIN [DB1].[dbo].[HealthCards] c on x.HealthCardId = c.Id
INNER JOIN [DB2].[pr].[TABLE] p on p.Id = c.TABLEId
INNER JOIN [DB3].[orgs].[Organizations] g on g.Id = x.OrganisationId
INNER JOIN [DB4].[dbo].ExitStateTypes t on t.Id = s.ExitStateTypeId
WHERE s.Id = (SELECT MAX(es.Id) from ExitStates es WHERE es.ExitId=x.Id)
ORDER BY s.InsertDate
So, I want partition by s.ExitStateTypeId just when it is 4 or 7 and -1 for the others
This is data I expect
Perhaps with a combination of CASE and ROW_NUMBER:
SELECT Number = CASE WHEN s.ExitStateTypeId NOT IN (4,7) THEN -1
ELSE Row_number() OVER (
partition BY s.exitstatetypeid
ORDER BY s.insertdate) END,
x.id,
p.firstname,
p.lastname,
p.pn,
t.name,
s.exitstatetypeid AS [Status],
g.name,
x.organisationid,
d.name AS Direction,
d.id AS DirectionId,
h.name AS Referal,
h.id AS HealthOrgTypeId,
s.issuedate,
s.insertdate
FROM [DB1].[dbo].[exits] x
INNER JOIN [DB1].[dbo].[exitstates] s
ON x.id = s.exitid
INNER JOIN [DB1].[dbo].[healthorgtypes] h
ON x.healthorgtypeid = h.id
INNER JOIN [DB1].[dbo].[directions] d
ON x.directionid = d.id
INNER JOIN [DB1].[dbo].[healthcards] c
ON x.healthcardid = c.id
INNER JOIN [DB2].[pr].[table] p
ON p.id = c.tableid
INNER JOIN [DB3].[orgs].[organizations] g
ON g.id = x.organisationid
INNER JOIN [DB4].[dbo].exitstatetypes t
ON t.id = s.exitstatetypeid
WHERE s.id = (SELECT Max(es.id)
FROM exitstates es
WHERE es.exitid = x.id)
ORDER BY s.insertdate
Get row numbers, left outer join and set null row number value to -1 (like below, might have to fix it up a bit as I don't have a schema to work with):
;with RowNumber( ExitId, RowNumber )
as
(
SELECT
x.Id
, ROW_NUMBER() OVER (PARTITION BY s.ExitStateTypeId ORDER BY s.InsertDate)
FROM
[DB1].[dbo].[Exits] x
INNER JOIN [DB1].[dbo].[ExitStates] s
on x.Id = s.ExitId
WHERE
s.Id = (SELECT MAX(es.Id) from ExitStates es WHERE es.ExitId=x.Id)
and s.ExitStateTypeId in ( 4, 7 )
)
SELECT
ISNULL( rn.RowNumber, -1 ) AS Number
,x.Id
,p.FirstName
,p.LastName
,p.PN
,t.Name
,s.ExitStateTypeId as [Status]
,g.Name
,x.OrganisationId
,d.Name AS Direction
,d.Id AS DirectionId
,h.Name AS Referal
,h.Id AS HealthOrgTypeId
,s.IssueDate
,s.InsertDate
FROM [DB1].[dbo].[Exits] x
INNER JOIN [DB1].[dbo].[ExitStates] s on x.Id = s.ExitId
INNER JOIN [DB1].[dbo].[HealthOrgTypes] h on x.HealthOrgTypeId = h.Id
INNER JOIN [DB1].[dbo].[Directions] d on x.DirectionId = d.Id
INNER JOIN [DB1].[dbo].[HealthCards] c on x.HealthCardId = c.Id
INNER JOIN [DB2].[pr].[TABLE] p on p.Id = c.TABLEId
INNER JOIN [DB3].[orgs].[Organizations] g on g.Id = x.OrganisationId
INNER JOIN [DB4].[dbo].ExitStateTypes t on t.Id = s.ExitStateTypeId
left outer join RowNumber rn
on x.Id = rn.ExitId
WHERE s.Id = (SELECT MAX(es.Id) from ExitStates es WHERE es.ExitId=x.Id)
ORDER BY s.InsertDate