Got 2 tables as shown above. I want to update 'leaverecord.Consumed' from 'approved.Consumed' WHERE the leaverecord.name = approved.name and leaverecord.leavetype = approved.leavetype. Tried below query by getting error of 'Invalid use of group function
UPDATE leaverecord r INNER JOIN approved a
ON r.name = a.name
SET r.Consumed = SUM(DATEDIFF(a.todate,a.fromdate))
WHERE r.leavetype = a.leavetype AND
r.name = a.name
Calculate the consumed in a subquery and INNER JOIN it with leaverecord and then do the UPDATE like below. No WHERE clause needed.
Try this:
update leaverecord r
inner join (
select name, leavetype, sum(datediff(todate,fromdate)) consumed
from approved
group by name, leavetype
) a on r.name = a.name
and r.leavetype = a.leavetype
set r.consumed = a.consumed;
Related
I have this query which i believe can be optimized:
SELECT floors.id, floors.floor FROM floors
WHERE floors.societies_id = 1
AND floors.status = 'Y'
AND floors.id NOT IN (
SELECT DISTINCT(floors.id) FROM floors
INNER JOIN societies ON societies.id = floors.societies_id
INNER JOIN resident_floors ON resident_floors.floors_id = floors.id
WHERE societies.id = 1
AND floors.status = 'Y'
)
Is this query fine to use or there it can be improved..?
It looks like you want to get all floors that aren't present in resident_floors. For this we can left join RF in and ask for only rows where the join failed resulting in a null in RF:
SELECT floors.* FROM floors
INNER JOIN societies ON societies.id = floors.societies_id
LEFT JOIN resident_floors ON resident_floors.floors_id = floors.id
WHERE societies.id = 1
AND floors.status = 'Y'
AND resident_floors.floors_id IS NULL
I have the following query:
SELECT e_c.*, c.name, j.status, j.version, j.articleId, j.title FROM assetcategory AS c
INNER JOIN assetentries_assetcategories AS e_c
ON c.categoryId = e_c.categoryId AND c.name = 'news'
INNER JOIN assetentry AS e
ON e.entryId = e_c.entryId
INNER JOIN journalarticle AS j
ON j.resourcePrimKey = e.classPK
AND e.classNameId = (SELECT classNameId FROM classname_ WHERE value = 'com.liferay.portlet.journal.model.JournalArticle')
AND j.companyId= e.companyId
WHERE j.status = 0
which returns all the category news in the journalarticles. From the results I need to select the most recent versions for each articleId. For example suppose there is an article with 4 versions, even with different title, it is the same article because it will have the same articleId. So therefore for each unique articleId I need the latest version. How can I do that?
Add a join to a subquery which finds the most recent version for each article:
SELECT e_c.*, c.name, j1.status, j1.version, j1.articleId, j1.title
FROM assetcategory AS c
INNER JOIN assetentries_assetcategories AS e_c
ON c.categoryId = e_c.categoryId AND c.name = 'news'
INNER JOIN assetentry AS e
ON e.entryId = e_c.entryId
INNER JOIN journalarticle AS j1
ON j1.resourcePrimKey = e.classPK AND
e.classNameId = (SELECT classNameId FROM classname_
WHERE value = 'com.liferay.portlet.journal.model.JournalArticle') AND
j.companyId = e.companyId
INNER JOIN
(
SELECT articleId, MAX(version) AS max_version
FROM journalarticle
WHERE status = 0
GROUP BY articleId
) j2
ON j1.articleId = j2.articleId AND j1.version = j2.max_version;
The basic idea behind the join to the subquery aliased as j2 above is that it restricts the result set to only the most recent version of each article. We don't necessarily have to change the rest of the query.
I am trying to run this query with using subquery but not able to fetch my result .is any one here to help me in geting it correct.
SELECT u.uv_id ID
, d.sd_code Code
, u.uv_name Title
, u.uv_nirf Nirf
, (SELECT sd_code
FROM vm_university_type t
JOIN vm_seo_detail d
ON t.ut_id = d.sd_ty_id
AND d.sd_ty = 'vm_university_type') AS 'University Type'
, a.ab_name 'Approved By'
, u.uv_seats Seats
, g.ug_name 'University Group'
FROM vm_universities u
JOIN vm_seo_detail d
ON u.uv_id = d.sd_ty_id
AND d.sd_ty = 'vm_universities'
JOIN vm_university_type t
ON u.uv_ut_id = t.ut_id
JOIN vm_approved_by a
ON u.uv_ab_id = a.ab_id
JOIN vm_caste c
ON u.uv_c_id = c.caste_id
JOIN vm_university_groups g
ON u.uv_ug_ids = g.ug_id;
i got this error Subquery returns more than 1 row
(SELECT `sd_code` FROM vm_university_type INNER JOIN vm_seo_detail ON (vm_university_type.ut_id = vm_seo_detail.sd_ty_id AND vm_seo_detail.sd_ty = 'vm_university_type') WHERE vm_university_type.ut_id=vm_universities.uv_ut_id ) AS 'University Type' ,
You do not need subquery at all. The column Code in SELECT statement contains University Type
Try below query.
SELECT vm_universities.uv_id AS 'ID' , vm_seo_detail.sd_code AS 'Code',
vm_universities.uv_name AS 'Title' , vm_universities.uv_nirf AS 'Nirf',
vm_approved_by.ab_name AS 'Approved By' , vm_universities.uv_seats as 'Seats',
vm_university_groups.ug_name AS 'University Group'
FROM vm_universities INNER JOIN vm_seo_detail
ON (vm_universities.uv_id = vm_seo_detail.sd_ty_id
AND vm_seo_detail.sd_ty = 'vm_universities')
INNER JOIN vm_university_type
ON (vm_universities.uv_ut_id = vm_university_type.ut_id)
INNER JOIN vm_approved_by
ON (vm_universities.uv_ab_id = vm_approved_by.ab_id)
INNER JOIN vm_caste
ON (vm_universities.uv_c_id = vm_caste.caste_id)
INNER JOIN vm_university_groups
ON (vm_universities.uv_ug_ids = vm_university_groups.ug_id);
SELECT `sd_code` FROM vm_university_type INNER JOIN vm_seo_detail ON (vm_university_type.ut_id = vm_seo_detail.sd_ty_id AND vm_seo_detail.sd_ty = 'vm_university_type')
looks like you forgot WHERE section in subquery, that will bind it to main query. something like
WHERE vm_university_type.ut_id=vm_universities.uv_ut_id
ps. and why you need this subquery at all, if you already join with vm_university_type in main query?
I don't know why my case code is having an error but when I execute it not using a parameter by replacing the #PersonId by 2 it runs well. I try to exchange2x the JOIN but I am still having an error. Anyone knows?.
case when ISNULL(dbo.EducationalBackground.SchoolId,'') = '' then
(Select a.SchoolName
from dbo.EducationalBackground as A INNER JOIN
dbo.PersonEducationalBackground as B on a.EducationalBackgroundId = b.EducationalBackgroundId INNER JOIN
dbo.EducationLevel as C on a.EducationalLevelId = c.EducationLevelId
where b.PersonId = #PersonId and a.EducationalLevelId in (2,3))
else (select dbo.school.SchooldName from dbo.School INNER JOIN dbo.EducationalBackground
ON dbo.School.SchoolId = dbo.EducationalBackground.SchoolId INNER JOIN
dbo.PersonEducationalBackground ON dbo.EducationalBackground.EducationalBackgroundId = dbo.PersonEducationalBackground.EducationalBackgroundId
where dbo.PersonEducationalBackground.PersonId = #PersonId)
Cheers. Thanks.
I run the above sql statement and i got this.[IMG]http://i1093.photobucket.com/albums/i422/walkgirl_1993/asd-1_zps5506632e.jpg[/IMG] i'm trying display the latest date which you can see the 3 and 4. For caseid 3, it should display the latest row which is the 2012-12-20 16:12:36.000. I tried using group by, order by. Google some website said to use rank but i'm not sure about the rank as i dont really get rank. Some suggestions?
select [Case].CaseID, Agent.AgentName, Assignment.Description, A.AgentName as EditedBy, A.DateEdited from Agent inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID inner join [Case] on [Case].CaseID = [Case-Agent].CaseID inner join (select EditedCase.CaseID, [EditedCase].DateEdited, [Agent].AgentName from EditedCase inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
To do it using RANK you just need to add the RANK to the subquery and get to rank the DateEdited for each CaseID and Agent and then in the main query put a WHERE clause to only select rows where the rank is 1. I think I have got the partition clause right - its a bit hard without seeing your data.
Like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,[EditedCase].DateEdited
,[Agent].AgentName
,RANK ( ) OVER (PARTITION BY EditedCase.CaseID, [Agent].AgentName
ORDER BY [EditedCase].DateEdited DESC ) AS pos
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You could also change the sub query into an aggregate query that brings back the MAX date like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,MAX([EditedCase].DateEdited) AS DateEdited
,[Agent].AgentName
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID
GROUP BY
EditedCase.CaseID
,[Agent].AgentName) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You were on the right track; you need to use a ranking function here, for example row_number():
with LatestCase as
(
select [Case].CaseID
, Agent.AgentName
, Assignment.Description
, A.AgentName as EditedBy
, A.DateEdited
, caseRank = row_number() over (partition by [Case].CaseID order by A.DateEdited desc)
from Agent
inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID
inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID
inner join [Case] on [Case].CaseID = [Case-Agent].CaseID
inner join
(
select EditedCase.CaseID
, [EditedCase].DateEdited
, [Agent].AgentName
from EditedCase
inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID
) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
)
select *
from LatestCase
where caseRank = 1