Hi all I have written the following query to combine the results from 3 tables(tblQuestions,tblReplies,tblTechnology and display the required results as follows
SELECT tech.DatePosted,
tech.QuestionID,
tech.TechnologyName,
tblr3.TechID,
tblr3.QuestionTitle,
tblr3.UserName,
tblr3.ReplyCount,
tblr3.viewCount,
tblr3.date,
tblr3.RepliedName
FROM (SELECT tblr1.DatePosted,
tblr1.QuestionID,
tblr2.TechID,
tblr2.QuestionTitle,
tblr2.UserName,
tblr2.ReplyCount,
tblr2.viewCount,
tblr1.date,
tblr1.RepliedName
FROM (SELECT tblq.DatePosted,
tblq.TechID,
tblq.QuestionID,
tblq.RepliedName,
tblq.QuestionTitle,
tblq.UserName,
tblq.ReplyCount,
tblq.viewCount,
tblq.date
FROM (SELECT q.DatePosted,
q.TechID,
q.QuestionID,
q.QuestionTitle,
q.UserName,
q.ReplyCount,
q.viewCount,
r.date,
r.UserName AS RepliedName
FROM tblQuestions AS q, tblReplies AS r
WHERE r.QuestionID = q.QuestionID
AND r.TechID = q.TechID
AND q.TechID = 1) AS tblq,
(SELECT r.QuestionID,
max(r.date) AS PostedDate
FROM tblReplies AS r
GROUP BY QuestionID) AS tblr
WHERE tblq.QuestionID = tblr.QuestionID
AND tblq.date = tblr.PostedDate) AS tblr1
RIGHT OUTER JOIN
(SELECT q.QuestionID,
q.TechID,
q.UserName,
q.viewCount,
q.ReplyCount,
q.QuestionTitle
FROM tblQuestions AS q
WHERE q.TechID = 1) AS tblr2
ON tblr2.QuestionID = tblr1.QuestionID) AS tblr3
LEFT OUTER JOIN
(SELECT q.QuestionID,
q.DatePosted,
t.TechID,
t.TechName AS TechnologyName
FROM tblTechnology AS t, tblQuestions AS q
WHERE q.TechID = t.TechID) AS tech
ON tblr3.TechID = tech.TechID
AND tblr3.QuestionID = tech.QuestionID
AND tech.TechID = 1
Which gives me the following result as expected but getting NULL at some fields where data to be present
In place of NULL i need to pull out some data which is present in tblQuestions, also is it possible to reduce the query.
From OPs Comment:
I am trying to pull out the questiontitle,username,questionid from tblquestions along with replycount and viewcount and the latest replys that are posted for that questions based on QuestionID and Technology ID from tblreplys
Your query is basically this:
SELECT
blah
FROM
(
(SELECT
blah
FROM
Questions
INNER JOIN Replies ON QuestionID AND TechID) tblr1
RIGHT JOIN Questions tblr2 ON QuestionID
) tblr3
LEFT JOIN Technologies ON tblr3.tblr1.QuestionID = Technologies.QuestionID
I know that isn't a valid query but bear with me. tblr1contains an INNER JOIN between questions and answers. However because there are no answers to the salary question these records are NULLfor the salaryquestion. The RIGHT JOIN to Questions then introduces the salary question and that exists in the tblr3 result set because it is a RIGHT JOIN even though tblr1 is null for this question.
The LEFT JOIN then to technologies is based on the QuestionID within tblr3 which is really the QuestionID from tblr1. From looking at the column list for the tblr3 sub query, if you change tblr1.QuestionID to tblr2.QuestionID this will ensure that unanswered questions join on to the Technology table
EDIT: I think the following query will give you your results and is much simpler:
WITH LatestReplies AS
(
SELECT
ReplyID,
QuestionID,
ReplyDate,
UserName,
Reply
FROM
(SELECT
ReplyID,
QuestionID,
ReplyDate,
UserName,
Reply,
ROW_NUMBER() OVER (PARTITION BY QuestionID ORDER BY ReplyDate DESC) ReplyOrder
FROM
tblReplies) A
WHERE
ReplyOrder = 1
)
SELECT
tblQuestions.DatePosted,
tblQuestions.QuestionID,
tblTechnology.TechnologyName,
tblQuestions.TechID,
tblQuestions.QuestionTitle,
tblQuestions.UserName,
tblQuestions.ReplyCount,
tblQuestions.ViewCount,
LatestReplies.ReplyDate,
LatestReplies.UserName RepliedName
FROM
tblQuestions
LEFT JOIN tblTechnology ON tblQuestions.TechID = tblTechnology.TechID
LEFT JOIN LatestReplies ON tblQuestions.QuestionID = LatestReplies.QuestionID
Solved with the following after all
select
FI.QuestionID,
FI.QuestionTitle,
FI.UserName,
FI.DatePosted,
FI.[date],
FI.RepliedName,
FI.viewCount,
FI.ReplyCount,
FI.ReplyMsg,
TT.TechID,
TT.TechName
from
tblTechnology TT,
(select distinct
TQ.TechID,
TQ.QuestionID,
TQ.QuestionTitle,
TQ.UserName,
TQ.DatePosted,
TR.[date],
TR.UserName as RepliedName,
TQ.viewCount,
TQ.ReplyCount,
TR.ReplyMsg
from
tblQuestions TQ
LEFT OUTER JOIN tblReplies TR ON
TR.TechID=TQ.TechID
and TR.QuestionID = TQ.QUESTIONID
and TR.[date] in (select
MAX(TR.[date])
from
tblReplies TR
group by
TR.QuestionID)
) FI
where
FI.TechID=TT.TechID
and TT.TechID=#TechID
Related
I'm working on a similar problem to check if a column contains ALL the values of another column - Mysql
This CTE is part of a bigger query. CTE_ProjekteRollen contains a subset of ProjektParamRolle and can contain zero or more records. I want a list of ProjektParam where the items in CTE_ProjekteRollen are all present (when joined with ProjektParamRolle). My solution works in all cases where CTE_ProjektRollen is not empty.
CTE_FilteredByRolle as (
select pp.ID_ProjektParam
from Basis.ProjektParam pp
join Basis.ProjektParamRolle ppr
on pp.ID_ProjektParam = ppr.ID_ProjektParam
join CTE_ProjektRollen pr
on ppr.Rolle = pr.Rolle
group by pp.ID_ProjektParam
having Count(pp.ID_ProjektParam) = (
select Count(Rolle)
from CTE_ProjektRollen))
What do I have to change to get all ProjektParam (joined with ProjektParamRolle), if CTE_ProjektRollen is empty?
Edit: I think I phrased my question wrong, because I didn't understand it fully. #Kendle's solution works for what I described, but I actually needed all ID_ProjektParam (not joined with ProjektParamRolle).
The actual CTE that worked for me was
CTE_FilteredByRolle as (
select pp.ID_ProjektParam
from Basis.ProjektParam pp
where (
select Count(ppr.Rolle)
from Basis.ProjektParamRolle ppr
join CTE_ProjektRollen pr
on ppr.Rolle = pr.Rolle
where ppr.ID_ProjektParam = pp.ID_ProjektParam) = (
select Count(Rolle)
from CTE_ProjektRollen))
We can use a CASE to check whether the table is empty. If it is empty we return the number to which we are comparing, so it will always be true.
CTE_FilteredByRolle as (
select pp.ID_ProjektParam
from Basis.ProjektParam pp
join Basis.ProjektParamRolle ppr
on pp.ID_ProjektParam = ppr.ID_ProjektParam
join CTE_ProjektRollen pr
on ppr.Rolle = pr.Rolle
group by pp.ID_ProjektParam
having Count(distinct pp.ID_ProjektParam)
= case when(select Count(distinct Rolle) from CTE_ProjektRollen)) = 0
then Count(distinct pp.ID_ProjektParam)
else (select Count(distinct Rolle) from CTE_ProjektRollen))
end;
So, full disclosure, this is my first time using a pivot table and the result set has multiple columns as a result. In this example, we will use the result set without a pivot table applied.
This student has taken multiple courses. What the ideal end result would be, is to count how many courses this student has taken. So if I look I see that the Student has taken Algebra 1 5 times, English 1 2 times and Geometry 2 times.
The Next image is the query with the pivot applied, oh and to make things complicated, its a monster query before trying to attempt the pivot.
So we see in this, that Algebra 1 has a count of 0, Geometry has a count of 2 and English has a count of 0. This is the same query as before but just using this student.
Query:
SELECT *
FROM
(SELECT
[StudentNumber], psat.MathScaledScore, psat.EBRWScore,
SCReady.MathScaleScore, SCReady.ReadingScaleScore,
SpringMap.MathPercentile, SpringMap.ReadingPercentile,
Coursework.Course_name
FROM
[OnlineApplications].[dbo].[Users] U
LEFT JOIN
[OnlineApplications].[dbo].ContactInfoes C ON C.ContactInfoId = U.UserId
LEFT JOIN
(SELECT *
FROM [DOENRICH-SQL].[enrich_prod].dbo.HCS_view_Most_Recent_PSAT_Scores Scores) AS psat ON U.StudentNumber = psat.number
LEFT JOIN
(SELECT
stud.Number, sc.DateTaken,
CASE sc.ELALev
WHEN 'E8AE0E4D-AD36-41D8-AC89-627D19661803' THEN 'Exceeds Expectations'
WHEN 'C9F2CDA2-D904-438B-9DD3-94EFC9111A0E' THEN 'Approaches Expectations'
WHEN '9B39E28F-89C8-44AD-A8F2-1463192F88F1' THEN 'Does Not Meet Expectation'
WHEN '87247DB1-4A57-419E-9619-7B43B02B1135' THEN 'Meets Expectations'
END ELALev,
sc.ELASS AS ELAScaleScore, sc.elavss AS VerticalScaleScore,
sc.elassread AS ReadingScaleScore,
sc.ELARS10 AS RawScoreStandard10, sc.elASPR AS ELAStatePercentileRank,
MathLev = CASE MathLev
WHEN 'E8AE0E4D-AD36-41D8-AC89-627D19661803' THEN 'Exceeds Expectations'
WHEN 'C9F2CDA2-D904-438B-9DD3-94EFC9111A0E' THEN 'Approaches Expectations'
WHEN '9B39E28F-89C8-44AD-A8F2-1463192F88F1' THEN 'Does Not Meet Expectation'
WHEN '87247DB1-4A57-419E-9619-7B43B02B1135' THEN 'Meets Expectations'
END,
sc.MATHSS AS MathScaleScore, sc.MathVSS AS MathVerticalScaleScore,
sc.mathspr AS MathStatePercentileRank
FROM
[DOENRICH-SQL].[enrich_prod].dbo.t_sc_ready sc
JOIN
[DOENRICH-SQL].[enrich_prod].dbo.Student stud ON sc.StudentID = stud.ID
WHERE
DateTaken = '2019-05-17') AS SCReady ON SCReady.number = U.studentnumber
LEFT JOIN
(
select stud.Number, max(map.readingPercentile) as ReadingPercentile, max(map.mathPercentile) as MathPercentile
from [DOENRICH-SQL].[ENRICH_PROD].[dbo].t_map map
join [DOENRICH-SQL].[ENRICH_PROD].[INFORM].[Map_GradeLevelID] mapping on map.GradeLevelID = mapping.DestID
JOIN [DOENRICH-SQL].[ENRICH_PROD].[dbo].[Student] stud on map.StudentID = stud.ID
where DateTaken >= '2018-08-01'
group by stud.Number
) as SpringMap on SpringMap.number = U.Studentnumber
left join (
SELECT * FROM OPENQUERY(PSPROD,'
Select B.STUDENT_NUMBER , A.COURSE_NAME, A.GRADE_LEVEL, A.SCHOOLNAME, A.GRADE
from PS.STOREDGRADES A
join PS.STUDENTS B ON A.STUDENTID = B.ID
AND STORECODE in (''Q1'',''Q2'',''Q3'',''Q4'',''F1'')
AND (COURSE_NAME LIKE ''%Algebra 1%'' OR COURSE_NAME LIKE ''%Geometry Honors%'' OR COURSE_NAME LIKE ''%English 1%'')
group by B.STUDENT_NUMBER , A.COURSE_NAME, a.STORECODE, A.GRADE, A.PERCENT, A.GRADE_LEVEL, A.SCHOOLNAME
ORDER BY STUDENT_NUMBER, STORECODE DESC
'
)
) as Coursework on Coursework.STUDENT_NUMBER = U.StudentNumber
join [OnlineApplications].[dbo].ScholarsApps Sapps on Sapps.ScholarsAppId = u.UserId
where AppYear = 2019 and StudentNumber <> '' and StudentNumber = '17476'
) T
PIVOT (
COUNT (COURSE_NAME)
FOR course_name IN (
[Algebra 1],
[Geometry Honors],
[English 1])
)
as Pivot_table
Again, very complicated query before and I'm not clear if I'm using the pivot function correctly.
I'd love to have this pivot with the counts of the courses.
I'm using a vendor supplied Relay Database (Aspen), which is running on MS SQL server). I'm attempting to write a pivot query that needs to pivot on 2 columns.
I created a temp table since the data is across multiple tables.
WITH TEMP_TABLE AS (
SELECT
R.LOCATIONID LLOCATIONID, R.ID RID, s.groupname SGROUPNAME,t.settingname TSETTINGNAME, s.setting SSETTING
from tsetting1 s
inner join tsettype1 t on t.relaytype=s.relaytype and t.groupname = s.groupname and t.rownumber = s.rownumber
INNER JOIN TREQUEST Q ON S.REQUESTID = Q.ID
INNER JOIN TRELAY R ON R.ID = Q.RELAYID
INNER JOIN TLOCATION L ON L.ID = R.LOCATIONID
where s.requestid=29117
)
select * from TEMP_TABLE
That select all from Temp returns 38 rows of data, a subset is shown here:
RID -----SGROUPNAME------TSETTINGNAME-------SSETTING
31297 LOAD1 ENABLE TRUE
31297 LOAD1 ANGLE 60
31297 LOAD2 CALCULATED_LOAD 12269
ETC....
I added this pivot, which gets me close:
PIVOT (MAX(SSETTING) FOR TSETTINGNAME IN (ENABLE, REACH, ANGLE, CALCULATED_LOADABILITY, ZLE, CTR, PTR, KVNOM, PICKUP, PERCENTAGE)) P
Returned result from Pivot:
RID-----SGROUPNAME-----ENABLE----REACH----ANGLE----CALCULATED_LOADABILITY
31297 LOAD1 TRUE 15 60 9444
31297 LOAD2 TRUE 10 30 12269
31297 LOAD3 TRUE 20 60 14167
ETC...
I would like to have the data as 1 record for RID 31297, where LOAD1-ENABLE, LOAD2-ENABLE, LOAD3-ENABLE, LOAD1-REACH, ETC. are all headers.
I've tried multiple pivots and cross apply, but I can't seem to get the data to display correctly.
Let me know if anything is unclear or if you need more information. Any help will be greatly appreciated.
Thanks,
Joe C.
It may be easier with a bunch of case statements and a group by RID. By the way this is the "original" method of pivoting before PIVOT was implemented.
select RID
, Load1_Enable = MAX(case when SGROUPNAME = 'Load1' then enable else null end)
, Load2_Enable = MAX(case when SGROUPNAME = 'Load2' then enable else null end)
from [YourTable]
group by RID
I would go all the way to the first cte though:
WITH TEMP_TABLE AS (
SELECT
R.LOCATIONID LLOCATIONID, R.ID RID, s.groupname SGROUPNAME,t.settingname TSETTINGNAME, s.setting SSETTING
from tsetting1 s
inner join tsettype1 t on t.relaytype=s.relaytype and t.groupname = s.groupname and t.rownumber = s.rownumber
INNER JOIN TREQUEST Q ON S.REQUESTID = Q.ID
INNER JOIN TRELAY R ON R.ID = Q.RELAYID
INNER JOIN TLOCATION L ON L.ID = R.LOCATIONID
where s.requestid=29117
)
select RID
,Load1_Enable = MAX(case when SGROUPNAME = 'Load1' and TSETTINGNAME = 'Enable' then SSETTING else null end)
from TEMP_TABLE
group by RID
Note MAX is only there for an aggregate -- you should be aggregating only one record.
I am running a query in SQL on our EHR/EMR database. I am primarily looking at an assessment that is done by a nurse during each patient encounter/visit and looking to return an answer for the most recent assessment date along with some other info. I have the query created and all the data is coming over, however, it is returning all assessment dates and the answers instead of just the latest date and answer. I'll attach the full code below.
SELECT DISTINCT
MAX(PTA.ASSESSMENT_DATE) AS Max_Date,
SAQ.QUESTION_TEXT, SAA.ANSWER_TEXT, dbo.PT_BASIC.PATIENT_CODE,
dbo.PT_BASIC.NAME_FULL
FROM
dbo.PTC_ASSESSMENT_ANSWER AS PAA
INNER JOIN
dbo.PTC_ASSESSMENT AS PTA ON PTA.ASSESSMENT_ID = PAA.ASSESSMENT_ID
AND PTA.PATIENT_ID = PAA.PATIENT_ID
INNER JOIN
dbo.SYS_ASSESSMENT_POINTER AS SAP ON SAP.POINTER_ID = PAA.POINTER_ID
INNER JOIN
dbo.SYS_ASSESSMENT_QUESTION AS SAQ ON SAQ.QUESTION_ID = SAP.QUESTION_ID
INNER JOIN
dbo.SYS_ASSESSMENT_ANSWER AS SAA ON SAA.ANSWER_ID = SAP.ANSWER_ID
INNER JOIN
dbo.PT_BASIC ON PTA.PATIENT_ID = dbo.PT_BASIC.PATIENT_ID
WHERE
(PTA.ASSESSMENT_DATE BETWEEN CONVERT(DATETIME, '2017-09-05 00:00:00', 102)
AND CONVERT(DATETIME, '2017-10-12 00:00:00', 102))
GROUP BY
dbo.PT_BASIC.PATIENT_CODE, dbo.PT_BASIC.NAME_FULL, SAQ.QUESTION_TEXT,
SAA.ANSWER_TEXT
HAVING
(SAA.ANSWER_TEXT LIKE '%LEVEL % -%')
The current output would be something similar to this:
9/5/2017 PATIENT ABC Answer1
9/6/2017 PATIENT ABC Answer2
9/7/2017 PATIENT ABC Answer3
9/6/2017 PATIENT XYZ Answer4
What I am expecting is:
9/7/2017 PATIENT ABC Answer3
9/6/2017 PATIENT XYZ Answer4
If your version of SQL Server supports it, using ROW_NUMBER() OVER() is an efficient and simple method for arriving at "latest" (or "earliest") rows from a single table. However as we know so little about your data model it isn't easy to guess how to reduce the rows to just the "lastest answer" which probably requires a more complex subquery. However you can still use ROW_NUMBER() OVER() on that subquery. I suspect that the nature of questions and answers is that the table aliases SAP, SAQ, SAA may all need to be involved in this subquery.
Note that instead of directly joining PTA this is now a subquery and the join condition to the outer query requires that RN=1 which is the row with the "latest" date.
SELECT
MAX(PTA.ASSESSMENT_DATE) AS Max_Date
, SAQ.QUESTION_TEXT
, SAA.ANSWER_TEXT
, dbo.PT_BASIC.PATIENT_CODE
, dbo.PT_BASIC.NAME_FULL
FROM dbo.PTC_ASSESSMENT_ANSWER AS PAA
INNER JOIN (
SELECT
*
, ROW_NUMBER() OVER (PARTITION BY PATIENT_ID
ORDER BY ASSESSMENT_DATE DESC) AS RN
FROM dbo.PTC_ASSESSMENT
WHERE ASSESSMENT_DATE BETWEEN '20170905' AND '20171012'
) AS PTA ON PTA.ASSESSMENT_ID = PAA.ASSESSMENT_ID
AND PTA.PATIENT_ID = PAA.PATIENT_ID
AND PTA.RN = 1
INNER JOIN dbo.SYS_ASSESSMENT_POINTER AS SAP ON SAP.POINTER_ID = PAA.POINTER_ID
INNER JOIN dbo.SYS_ASSESSMENT_QUESTION AS SAQ ON SAQ.QUESTION_ID = SAP.QUESTION_ID
INNER JOIN dbo.SYS_ASSESSMENT_ANSWER AS SAA ON SAA.ANSWER_ID = SAP.ANSWER_ID
INNER JOIN dbo.PT_BASIC ON PTA.PATIENT_ID = dbo.PT_BASIC.PATIENT_ID
WHERE SAA.ANSWER_TEXT LIKE '%LEVEL % -%'
GROUP BY
dbo.PT_BASIC.PATIENT_CODE
, dbo.PT_BASIC.NAME_FULL
, SAQ.QUESTION_TEXT
, SAA.ANSWER_TEXT
select distinct is not required on this query (or any similar query using GROUP BY)
yyymmdd is the safest date literal in SQL Server, you don't need the converts using style 102
your having clause should be moved to a where clause as it does not evaluate any aggregated value
Cross apply allows you to use a correlated query and chive the top most n records ordered by date desc for each patient assessment. (after review maybe you just need patient?)
Perhaps just change:
INNER JOIN
dbo.PTC_ASSESSMENT AS PTA ON PTA.ASSESSMENT_ID = PAA.ASSESSMENT_ID
AND PTA.PATIENT_ID = PAA.PATIENT_ID
TO:
CROSS APPLY (SELECT TOP 1 *
FROM dbo.PTC_ASSESSMENT PTA2
WHERE PTA2.ASSESSMENT_ID = PAA.ASSESSMENT_ID
/*AND PTA2.PATIENT_ID = PAA.PATIENT_ID*/
ORDER BY PTA2.Assessment_date desc) PTA
GIVING YOU: (I left the /AND PTA2.PATIENT_ID = PAA.PATIENT_ID/ --I think you can omit this. I left the */ in place but it's not needed)
SELECT MAX(PTA.ASSESSMENT_DATE) AS Max_Date
, SAQ.QUESTION_TEXT
, SAA.ANSWER_TEXT
, dbo.PT_BASIC.PATIENT_CODE
, dbo.PT_BASIC.NAME_FULL
FROM dbo.PTC_ASSESSMENT_ANSWER AS PAA
CROSS APPLY (SELECT TOP 1 *
FROM dbo.PTC_ASSESSMENT PTA2
WHERE PTA2.ASSESSMENT_ID = PAA.ASSESSMENT_ID --I think you can omit this.
/*AND PTA2.PATIENT_ID = PAA.PATIENT_ID*/
ORDER BY PTA2.Assessment_date desc) PTA
INNER JOIN dbo.SYS_ASSESSMENT_POINTER AS SAP
ON SAP.POINTER_ID = PAA.POINTER_ID
INNER JOIN dbo.SYS_ASSESSMENT_QUESTION AS SAQ
ON SAQ.QUESTION_ID = SAP.QUESTION_ID
INNER JOIN dbo.SYS_ASSESSMENT_ANSWER AS SAA
ON SAA.ANSWER_ID = SAP.ANSWER_ID
INNER JOIN dbo.PT_BASIC
ON PTA.PATIENT_ID = dbo.PT_BASIC.PATIENT_ID
WHERE (PTA.ASSESSMENT_DATE BETWEEN CONVERT(DATETIME, '2017-09-05 00:00:00', 102) AND CONVERT(DATETIME, '2017-10-12 00:00:00', 102))
GROUP BY dbo.PT_BASIC.PATIENT_CODE
, dbo.PT_BASIC.NAME_FULL
, SAQ.QUESTION_TEXT
, SAA.ANSWER_TEXT
HAVING (SAA.ANSWER_TEXT LIKE '%LEVEL % -%')
It appears you're not concerned about patients w/o assessments as all your joins are inner or we could use OUTER APPPLY to be sure to keep all answers regardless if an assessment has been provided.
Alternatively you could use a row_number() logic ( Tab Alleman's link has this covered) and a cte; but if cross apply is available might as well use it here.
Please include order by PTA.ASSESSMENT_DATE DESC to see the latest records at the top.
Ok here's my View (vw_LiftEquip)
SELECT dbo.tbl_equip_swl_unit.unit_id,
dbo.tbl_equip_swl_unit.unit_name,
dbo.tbl_equip_swl_unit.archived,
dbo.tbl_categories.category_id,
dbo.tbl_categories.categoryName,
dbo.tbl_categories.parentCategory,
dbo.tbl_categories.sub_category,
dbo.tbl_categories.desc_category,
dbo.tbl_categories.description,
dbo.tbl_categories.miscellaneous,
dbo.tbl_categories.category_archived,
dbo.tbl_equip_swl_unit.unit_name AS Expr1,
dbo.tbl_categories.categoryName AS Expr2,
dbo.tbl_categories.description AS Expr3,
dbo.tbl_equip_depts.dept_name,
dbo.tbl_equip_man.man_name,
dbo.tbl_Lifting_Gear.e_defects AS Expr7,
dbo.tbl_Lifting_Gear.e_defects_desc AS Expr8,
dbo.tbl_Lifting_Gear.e_defects_date AS Expr9,
dbo.tbl_equipment.equipment_id,
dbo.tbl_equipment.e_contract_no,
dbo.tbl_equipment.slID,
dbo.tbl_equipment.e_entered_by,
dbo.tbl_equipment.e_serial,
dbo.tbl_equipment.e_model,
dbo.tbl_equipment.e_description,
dbo.tbl_equipment.e_location_id,
dbo.tbl_equipment.e_owner_id,
dbo.tbl_equipment.e_department_id,
dbo.tbl_equipment.e_manafacture_id,
dbo.tbl_equipment.e_manDate1,
dbo.tbl_equipment.e_manDate2,
dbo.tbl_equipment.e_manDate3,
dbo.tbl_equipment.e_dimensions,
dbo.tbl_equipment.e_test_no,
dbo.tbl_equipment.e_firstDate1,
dbo.tbl_equipment.e_firstDate2,
dbo.tbl_equipment.e_firstDate3,
dbo.tbl_equipment.e_prevDate1,
dbo.tbl_equipment.e_prevDate2,
dbo.tbl_equipment.e_prevDate3,
dbo.tbl_equipment.e_insp_frequency,
dbo.tbl_equipment.e_swl,
dbo.tbl_equipment.e_swl_unit_id,
dbo.tbl_equipment.e_swl_notes,
dbo.tbl_equipment.e_cat_id,
dbo.tbl_equipment.e_sub_id,
dbo.tbl_equipment.e_parent_id,
dbo.tbl_equipment.e_last_inspector,
dbo.tbl_equipment.e_last_company,
dbo.tbl_equipment.e_deleted AS Expr11,
dbo.tbl_equipment.e_deleted_desc AS Expr12,
dbo.tbl_equipment.e_deleted_date AS Expr13,
dbo.tbl_equipment.e_deleted_insp AS Expr14,
dbo.tbl_Lifting_Gear.e_defects_action AS Expr15,
dbo.tbl_equipment.e_rig_location,
dbo.tbl_Lifting_Gear.e_add_type AS Expr17,
dbo.tbl_Lifting_Gear.con_id,
dbo.tbl_Lifting_Gear.lifting_date,
dbo.tbl_Lifting_Gear.lifting_ref_no,
dbo.tbl_Lifting_Gear.e_id,
dbo.tbl_Lifting_Gear.inspector_id,
dbo.tbl_Lifting_Gear.lift_testCert,
dbo.tbl_Lifting_Gear.lift_rig_location,
dbo.tbl_Lifting_Gear.inspected,
dbo.tbl_Lifting_Gear.lifting_through,
dbo.tbl_Lifting_Gear.liftingNDT,
dbo.tbl_Lifting_Gear.liftingTest,
dbo.tbl_Lifting_Gear.e_defects,
dbo.tbl_Lifting_Gear.e_defects_desc,
dbo.tbl_Lifting_Gear.e_defects_date,
dbo.tbl_Lifting_Gear.e_defects_action,
dbo.tbl_Lifting_Gear.lift_department_id,
dbo.tbl_Lifting_Gear.lifting_loc
FROM dbo.tbl_equipment
INNER JOIN dbo.tbl_equip_swl_unit
ON dbo.tbl_equipment.e_swl_unit_id = dbo.tbl_equip_swl_unit.unit_id
INNER JOIN dbo.tbl_categories
ON dbo.tbl_equipment.e_cat_id = dbo.tbl_categories.category_id
INNER JOIN dbo.tbl_equip_depts
ON dbo.tbl_equipment.e_department_id = dbo.tbl_equip_depts.dept_id
INNER JOIN dbo.tbl_equip_man
ON dbo.tbl_equipment.e_manafacture_id = dbo.tbl_equip_man.man_id
INNER JOIN dbo.vwSubCategory
ON dbo.tbl_equipment.e_sub_id = dbo.vwSubCategory.category_id
INNER JOIN dbo.vwDescCategory
ON dbo.tbl_equipment.e_cat_id = dbo.vwDescCategory.category_id
INNER JOIN dbo.tbl_Lifting_Gear
ON dbo.tbl_equipment.equipment_id = dbo.tbl_Lifting_Gear.e_id
And here's the select statement with subquery that I am using:
SELECT *
FROM vw_LiftEquip
WHERE lifting_loc = ? AND
con_id = ? AND
EXPR11 =
'N'(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
)
ORDER BY lifting_ref_no,
category_id,
e_swl,
e_serial
I get the error :
Column "vw_LiftEquip.category_id" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
Can't see why its returning that error, this is admittedly the first time I've ran a subquery on such a complex view, and I am a bit lost, thanks in advance for any help. I have looked through the similar posts and can find no answers to this one, sorry if I am just being dumb.
You are missing AND between EXPR11 = 'N' and (SELECT MAX(...
Otherwise, it looks OK. MAX without GROUP BY is allowed if you have no other columns in the SELECT
Update: #hvd also noted that you have nothing to compare to MAX(lifting_date). See comment
Update 2,
SELECT *
FROM vw_LiftEquip v1
CROSS JOIN
(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
) v2
WHERE v1.lifting_loc = ? AND
v1.con_id = ? AND
v1.EXPR11 = 'N'
ORDER BY v1.lifting_ref_no,
v1.category_id,
v1.e_swl,
v1.e_serial