SQL joins returning multiple results - sql

select
tmp.templatedesc Template
,sec.name Section
,q.questiontext Questions,
--,sum(case when q.responserequired = '0' then 1 else null end) as 'N/A'
--,sum(case when q.responserequired = '1' then 1 else null end) as Scored
--,count (case when (qr.weightedscore is not null and tmp.templatedesc = 'QA 30 Day Call Form' and
--sec.name = 'opening' and
--rv.reviewstatusid = 1 )then 1 else null end) as scored
----,(case when qr.weightedscore <> q.weight then rv.reviewid else null end) as fail
--count (case when qr.weightedscore is null then 1 else null end) NA,
--count (case when qr.weightedscore is not null then 1 else null end) scored,
sec.sequencenumber, q.questionnumber, qr.*
from
aqm.dbo.reviewtemplate tmp (nolock)
inner join aqm.dbo.section sec on sec.templateid =tmp.templateid
inner join aqm.dbo.sectionresult scr on scr.sectionid = sec.sectionid
inner join aqm.dbo.questionresult qr on qr.sectionresultid = scr.sectionresultid
inner join aqm.dbo.question q on q.questionid = qr.questionid
--inner join aqm.dbo.questiontype qt on qt.questiontypeid = q.questiontypeid
--left outer join aqm.dbo.questionoption qo on qo.questionid = q.questionid
inner join aqm.dbo.review rv on tmp.templateid = rv.templateid
inner join aqm.dbo.media md on md.mediaid = rv.mediaid
inner join aqm.dbo.iqmuser ut on md.userid = ut.userid
where
rv.reviewstatusid = 1 and
tmp.templatedesc = 'QA 30 Day Call Form'
and sec.name = 'opening' and
convert(varchar,dateadd(hh,-7,rv.reviewdate), 101) = '07/07/2014'
and ut.windowslogonaccount = 'name.name'
and q.questionnumber = 4
--group by
--tmp.templatedesc , sec.name, q.questiontext, sec.sequencenumber, q.questionnumber
order by
sec.sequencenumber, q.questionnumber
the questionresultid and sectionresultid are returning multiple values
how can i fix the joins so that it doesnt return multiple values?
i have it drilled down to a date and a person so that it should only return one row of results( but that obviously didnt work)
not sure what other data i can provide
update
i think it has to do with joins
inner join aqm.dbo.sectionresult scr on scr.sectionid = sec.sectionid
inner join aqm.dbo.questionresult qr on qr.sectionresultid = scr.sectionresultid
as those are the ones returning multiple results.
just dont know how to fix it

First, neither aqm.dbo.questiontype nor aqm.dbo.questionoption are used in your return fields or your where clause so get rid of them if they aren't required.
Second, you are OUTER JOINing on the aqm.dbo.review, but the reviewstatusid and reviewdate are required in the WHERE clause - so this should probably be an INNER JOIN.
Last, best way to debug issues like this is to comment out the COUNT statements and the GROUP BY clause - and see what raw data is being returned.

Related

wrongly totalling all rows and not just the ones with a certain value for a certain column [duplicate]

This question already has answers here:
Two SQL LEFT JOINS produce incorrect result
(3 answers)
Closed 9 months ago.
I may have messed up the joins or there may be another way of writing what I am trying to achieve.
My current query is this:
SELECT
i.SKI_NAME AS Description,
l.SKV_QUANTITY_IN_STOCK AS Qty,
SUM(CASE WHEN ad.AVN_STATUS = 'D' THEN li.AVL_QUANTITY ELSE '0' END) AS AdviceQty,
SUM(CASE WHEN con.HCT_STATUS = 'D' THEN item.HIT_QUANTITY ELSE '0' END) AS HireQty
FROM
TH_STOCK_LEVELS l
LEFT JOIN TH_STOCK_ITEMS i ON l.SKV_STOCK_NUMBER = i.SKI_STOCK_NUMBER
LEFT JOIN TH_ADVICE_NOTE_LINES li ON i.SKI_NAME = li.AVL_DESCRIPTION
LEFT JOIN TH_HIRE_ITEMS Item ON li.AVL_DESCRIPTION = Item.HIT_DESCRIPTION
LEFT JOIN TH_ADVICE_NOTES ad ON ad.AVN_ID = li.AVL_NOTE_NUMBER
LEFT JOIN TH_HIRE_CONTRACTS con ON con.HCT_CONTRACT_NUMBER = Item.HIT_CONTRACT_NUMBER
WHERE
l.SKV_DEPOT_ID = 7
GROUP BY i.SKI_NAME, l.SKV_QUANTITY_IN_STOCK;
This displays the following output:
Description
Qty
AdviceQty
HireQty
Some Item
2
400
100
Some Item
0
100
0
Which is incorrect, as it seems to be totalling all previous Advice's and Hire's and not just the ones with Status 'D'.
If I do the following to the query (comment some lines out):
SELECT
i.SKI_NAME AS Description,
l.SKV_QUANTITY_IN_STOCK AS Qty,
SUM(CASE WHEN ad.AVN_STATUS = 'D' THEN li.AVL_QUANTITY ELSE '0' END) AS AdviceQty
--SUM(CASE WHEN con.HCT_STATUS = 'D' THEN item.HIT_QUANTITY ELSE '0' END) AS HireQty
FROM
TH_STOCK_LEVELS l
LEFT JOIN TH_STOCK_ITEMS i ON l.SKV_STOCK_NUMBER = i.SKI_STOCK_NUMBER
LEFT JOIN TH_ADVICE_NOTE_LINES li ON i.SKI_NAME = li.AVL_DESCRIPTION
--LEFT JOIN TH_HIRE_ITEMS Item ON li.AVL_DESCRIPTION = Item.HIT_DESCRIPTION
LEFT JOIN TH_ADVICE_NOTES ad ON ad.AVN_ID = li.AVL_NOTE_NUMBER
--LEFT JOIN TH_HIRE_CONTRACTS con ON con.HCT_CONTRACT_NUMBER = Item.HIT_CONTRACT_NUMBER
WHERE
l.SKV_DEPOT_ID = 7
GROUP BY i.SKI_NAME, l.SKV_QUANTITY_IN_STOCK;
The output is correct, although I am now missing a column due to the comments. This also works if I comment out the Advice tables, the HireQty column would be correct.
Description
Qty
AdviceQty
Some Item
2
10
Some Item
0
0
How do I get this to display the correct data for both AdviceQty & HireQty without having to do them separately?
Sometimes, CASE statement doesn't work. You can try with IFs and see if it is working.
SELECT
i.SKI_NAME AS Description,
l.SKV_QUANTITY_IN_STOCK AS Qty, SUM(IF(ad.AVN_STATUS='D',li.AVL_QUANTITY,0)) AS AdviceQty, SUM(IF(con.HCT_STATUS='D',item.HIT_QUANTITY,0)) AS HireQty
FROM
TH_STOCK_LEVELS l
LEFT JOIN TH_STOCK_ITEMS i ON l.SKV_STOCK_NUMBER = i.SKI_STOCK_NUMBER LEFT JOIN TH_ADVICE_NOTE_LINES li ON i.SKI_NAME = li.AVL_DESCRIPTION LEFT JOIN TH_HIRE_ITEMS Item ON li.AVL_DESCRIPTION
= Item.HIT_DESCRIPTION LEFT JOIN TH_ADVICE_NOTES ad ON ad.AVN_ID = li.AVL_NOTE_NUMBER LEFT JOIN TH_HIRE_CONTRACTS con ON con.HCT_CONTRACT_NUMBER = Item.HIT_CONTRACT_NUMBER
WHERE
l.SKV_DEPOT_ID = 7
GROUP BY i.SKI_NAME, l.SKV_QUANTITY_IN_STOCK;

Convert multiple rows to columns but as one rows

How do i achieve achieve all this records under one row since every employee has one of each NHIF, NSSF and KRA number?
Below is the query i used but the all appear separate rows.
SELECT DISTINCT
hrmemployeehdr.employeeslno,
hrmemployeehdr.employeecode,
hrmemployeehdr.employeefirstname,
hrmemployeehdr.employeemiddlename,
hrmemployeehdr.employeelastname,
hrmDesignationHdr.DesignationName,
hrmemployeehdr.DateOfBirth,
hrmemployeehdr.DateOfJoin,
hlocationhdr.locationname,
hrmEmployeeIdentityDtl.IDProofReferenceNo AS [National ID],
(CASE
WHEN hrmEmployeeDeductionSettingsDtl.DeductionCode = 1 THEN hrmEmployeeDeductionSettingsDtl.EmployeeRegID
ELSE ''
END) AS NHIF,
(CASE
WHEN hrmEmployeeDeductionSettingsDtl.DeductionCode = 2 THEN hrmEmployeeDeductionSettingsDtl.EmployeeRegID
ELSE ''
END) AS NSSF,
(CASE
WHEN hrmEmployeeDeductionSettingsDtl.DeductionCode = 3 THEN hrmEmployeeDeductionSettingsDtl.EmployeeRegID
ELSE ''
END) AS KRA,
hrmemployeestatusdtl.Email AS [Employee Email],
huser.email AS [User Account Email],
hrmEmployeeGradeHdr.GradeName,
hDepartment.DepartmentName
FROM hrmemployeehdr
JOIN hrmemployeestatusdtl ON hrmemployeestatusdtl.employeeslno = hrmemployeehdr.employeeslno
JOIN hdivision ON hdivision.divisioncode = hrmemployeestatusdtl.divisioncode
JOIN hlocationhdr ON hlocationhdr.locationcode = hrmemployeestatusdtl.workinglocationcode
JOIN hDepartment ON hDepartment.DepartmentCode = hrmemployeestatusdtl.DepartmentCode
JOIN hrmDesignationHdr ON hrmDesignationHdr.DesignationCode = hrmemployeestatusdtl.DesignationCode
JOIN hrmEmployeeCategoryHdr ON hrmEmployeeCategoryHdr.CategoryCode = hrmemployeestatusdtl.CategoryCode
JOIN hrmEmployeeGradeHdr ON hrmEmployeeGradeHdr.GradeCode = hrmemployeestatusdtl.GradeCode
LEFT JOIN huser ON huser.employeeslno = hrmemployeehdr.employeeslno
JOIN hMasterValue ON hMasterValue.MasterValueID = hrmemployeestatusdtl.MasterValue_EmploymentStatusID
JOIN hrmEmployeeIdentityDtl ON hrmEmployeeIdentityDtl.EmployeeSlno = hrmemployeehdr.EmployeeSlno
INNER JOIN hMasterValue a ON a.MasterValueID = hrmEmployeeIdentityDtl.MasterValue_IDProofTypeID
INNER JOIN hrmEmployeeDeductionSettingsDtl ON hrmEmployeeDeductionSettingsDtl.EmployeeSlno = hrmemployeehdr.EmployeeSlno
LEFT JOIN hrmDeductionHdr ON hrmDeductionHdr.DeductionCode = hrmEmployeeDeductionSettingsDtl.DeductionCode
WHERE hrmemployeestatusdtl.employeeslno NOT IN (SELECT hrmemploymentstoppageandtermination.employeeslno
FROM hrmemploymentstoppageandtermination)
AND hrmEmployeeIdentityDtl.MasterValue_IDProofTypeID = 2741005
--and hrmemployeestatusdtl.email = huser.email
--and huser.isemployee = 1
-- select * from huser
ORDER BY employeefirstname ASC;
Use conditional aggregation on the detail table to condense all those rows into one for each employee. Something like:
with edet as (select employeeslno,
max(CASE DeductionCode when 1 THEN EmployeeRegID ELSE '' END) AS NHIF,
max(CASE DeductionCode when 2 THEN EmployeeRegID ELSE '' END) AS NSSF,
max(CASE DeductionCode when 3 THEN EmployeeRegID ELSE '' END) AS KRA
from dbo.hrmEmployeeDeductionSettingsDtl
group by employeeslno)
select emp.employeeslno, ...,
edet.NHIF, edet.NSSF, edet.KRA, ...
from dbo.hrmemployeehdr as emp
inner join edet on emp.employeeslno = edet.employeeslno
...
order by ...
;
Notice the formatting changes that HELP everyone read and understand the code as well as the good habits of using aliases, schema-qualified table names, statement terminator, etc. As already mentioned, the other joins might be contributing to the problem - but this addresses the 1:3 relationship between the header and detail table.

Joining two aggregate queries from the same table - SQL Server

I have two queries, both are aggregated from the same table. I'm not sure if I have to join these two queries together or if it can be done with one select statement. The goal is to output a table that aggregates total charges and total refunds for each student.
Query #1:
select
s.learners_id, sum(charge.total_amount) charge_amount
from
fact_student_transactions_t charge
inner join
dim_students_t s on s.students_sk_id = charge.students_sk_id
left join
object_statuses_t os on os.object_statusid = charge.transaction_status_id
where
os.status_name = 'Success'
and charge.tran_type = 'CHARGE'
and charge.curr_in = 1
group by
s.learners_id
Query #2:
select
s.learners_id, sum(refund.total_amount) refund_amount
from
fact_student_transactions_t refund
inner join
dim_students_t s on s.students_sk_id = refund.students_sk_id
left join
object_statuses_t os on os.object_statusid = refund.transaction_status_id
where
os.status_name = 'Success'
and refund.tran_type = 'Refund'
and refund.trans_description not in ('Amount Successfully Transfered to Prepaid Balance.', 'Amount Successfully Transfered.')
and refund.payment_method != 'Transfer'
and refund.curr_in = 1
group by
s.learners_id
You can use conditional aggregation. Also, because of the nature of the where clause, the left join is unnecessary -- the unmatched records are filtered out anyway.
So:
select s.learners_id,
sum(case when st.tran_type = 'CHARGE' then st.total_amount else 0 end) as charge_amount,
sum(case when st.tran_type = 'Refund' and
st.trans_description not in ('Amount Successfully Transfered to Prepaid Balance.', 'Amount Successfully Transfered.')
and
st.payment_method <> 'Transfer'
then st.total_amount else 0
end) as refund_amount
from fact_student_transactions_t st join
dim_students_t s
on s.students_sk_id = t.students_sk_id join
object_statuses_t os
on os.object_statusid = t.transaction_status_id
where os.status_name = 'Success' and
st.curr_in = 1 and
st.tran_type in ('CHARGE', 'Refund')
group by s.learners_id

Return a Count of 0 When No Rows

OK, I've looked this up and tried a number of solutions, but can't get it to work. I'm a bit of a novice. Here's my original query - how can I get it to return 0 for an account when there are no results in the student table?
SELECT a.NAME
,count(s.student_sid)
FROM account a
JOIN inst i ON a.inst_sid = i.root_inst_sid
JOIN inst_year iy ON i.inst_sid = iy.inst_sid
JOIN student s ON iy.inst_year_sid = s.inst_year_sid
WHERE s.demo = 0
AND s.STATE = 1
AND i.STATE = 1
AND iy.year_sid = 16
AND a.account_sid IN (
20187987
,20188576
,20188755
,52317128
,20189249
)
GROUP BY a.NAME;
Use an outer join, moving the condition on that table into the join:
select a.name, count(s.student_sid)
from account a
join inst i on a.inst_sid = i.root_inst_sid
join inst_year iy on i.inst_sid = iy.inst_sid
left join student s on iy.inst_year_sid = s.inst_year_sid
and s.demo = 0
and s.state = 1
where i.state = 1
and iy.year_sid = 16
and a.account_sid in (20187987, 20188576, 20188755, 52317128, 20189249)
group by a.name;
count() does not count null values, which s.student_sid will be if no rows join from student.
You need to LEFT JOIN and then SUM() over the group where s.student_sid is not null:
select
a.name,
sum(case when s.student_sid is null then 0 else 1 end) as student_count
from account a
join inst i on a.inst_sid = i.root_inst_sid
join inst_year iy on i.inst_sid = iy.inst_sid
left join student s
on iy.inst_year_sid = s.inst_year_sid
and s.demo = 0
and s.state = 1
where i.state = 1
and iy.year_sid = 16
and a.account_sid in (20187987, 20188576, 20188755, 52317128, 20189249)
group by a.name;
This is assuming that all of the fields in the student table that you are filtering on are optional. If you don't want to enforce removal of records where, say, s.state does not equal 1, then you need to move the s.state=1 predicate into the WHERE clauses.
If, for some reason, you are getting duplicate student IDs and students are being counted twice, then you can change the aggregate function to this:
count(distinct s.student_id) as student_count
...which is safe to do as count(distinct ...) ignores null values.

Column 'sip.sip.Application.Id' is invalid in the select list

i have an query that is returning "Column 'sip.sip.Application.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause" error. But i have already included that column in the group by. So i'm not sure why it's still returning this error.
SQL Query
SELECT DISTINCT
a.[ApplicationId]
,a.[Id]
,a.[CompanyId]
,c.name AS CompanyName
,a.[CourseSIPRunId]
,ss.[AdminNo]
,count(CASE ss.StudentStatusCode WHEN 'ASG' THEN 1 ELSE 0 END) NoOfStudentsAllocated
,project.NoOfStudents
,project.[CourseCode]
,a.[AppStatusCode]
,appstat.AppStatusDescription
,project.[ProjectId]
,project.ProjectDescription
,a.CourseSIPRunId
,siprun.[AcadYear] + '-' + siprun.[Batch] As SIPBatch
,c.CompanyUEN
,c.PostalCode AS CompanyPostalCode
,course.CourseName
,project.[ResearchFlag] AS ResearchFlagString
,project.MPFlag AS MPFlagString
,project.[SIPType]
,project.ProjectDescription
,case when project.[SIPType]='OSIP' then 1 else 0 END IsOSIP
,case when project.[ResearchFlag] ='Y' then 1 else 0 END IsResearch
,case when project.[MPFlag] ='Y' then 1 else 0 END IsResearch
,project.MentorProjectLeader
,a.[SpecialRequirement]
,a.[MthlyAllowance]
,a.[OtherAllowance]
,a.[DaysPerWeek]
,a.[WeekdayHoursFrom]
,a.[WeekdayHoursTo]
,a.[SaturdayHoursFrom]
,a.[SaturdayHoursTo]
,a.[SundayHoursFrom]
,a.[SundayHoursTo]
,a.[ShiftWorkRequirement]
,a.[TPContactStaffEmailId]
,a.[SIPConfirmationDate]
,a.[SIPConfirmationBy]
,a.[Remarks]
,a.[SelfSource]
,a.[CreateSource]
,a.[CreatedDate]
,a.[SIPAllocationDate]
,a.[SIPAllocationBy]
,a.[SIPClosureDate]
,a.[SIPClosedBy]
,a.[LastUpdatedBy]
,a.[LastUpdatedDate]
,a.[AppStatusCode]
,a.[StatusReason]
,a.[OSIPCountryCode]
,a.[OSIPState]
,a.[OSIPCity]
,a.[OSIPDetails]
,a.[OverseasAssignment]
,a.[OverseasFrequency]
,a.[OverseasOtherCountry]
,a.[OverseasCountryCode]
,a.[OSIPOtherCountry]
,a.[OthersDetails]
,a.[OthersTPContactName]
,a.[OthersTPDiploma]
,a.[OthersEngagement]
,siprun.[StartDate]
,siprun.[EndDate]
,case when appotherinfo.AppOptionCode is null then 0 else 1 END IsInterviewRequired
,appotherinfo.AppOptionCode
FROM [sip].[sip].[Application] a
LEFT join [sip].[ApplicationStatus] appstat on a.AppStatusCode = appstat.AppStatusCode
LEFT join [sip].[ApplicationProject] project on a.ApplicationId = project.ApplicationId
LEFT JOIN [sip].[ApplicationProjectLO] lo on project.ProjectId = lo.ProjectId
LEFT JOIN [sip].[StudentSIP] ss on ss.ProjectId = lo.ProjectId
LEFT JOIN [sip].[ApplicationProjectSupervisor] s on s.ProjectId = project.ProjectId
LEFT JOIN [sip].[Company] c on c.CompanyId = a.CompanyId
LEFT JOIN [sip].[CourseSIPRun] siprun on a.CourseSIPRunId = siprun.CourseSIPRunId
LEFT JOIN [sip].[V_SIP_COURSE] course on project.CourseCode = course.COURSECODE
LEFT JOIN [sip].[ApplicationOtherInfo] appotherinfo on appotherinfo.ApplicationId = a.ApplicationId
group by a.[ApplicationId]
You include a.[ApplicationId] you don't include a.[Id] The error message is about the 2nd one.