SQL, CUCM: query returns with no result - sql

Following SQL query in CUCM (11.5) cli returns with the following result:
device number loggedin_to_lg linegroup
=============== =============== ============== ======================================
CSFABCDEF \+49325874147 f LG-HG_BER01_49325874147
CSFRFETRS \+49325800848 f LG-HG_BER01_493225800848
run sql select d.name as Device, n.dnorpattern as Number, dhd.hlog as LoggedIn_to_LG, lg.name as LineGroup
from linegroup as lg
inner join linegroupnumplanmap as lgmap on lgmap.fklinegroup=lg.pkid
inner join numplan as n on lgmap.fknumplan = n.pkid
inner join devicenumplanmap as dmap on dmap.fknumplan=n.pkid
inner join device as d on dmap.fkdevice=d.pkid
inner join devicehlogdynamic as dhd on dhd.fkdevice=d.pkid
order by lg.name
However, if we try to inner join one more table -extensionmobilitydynamic- to this query and display one of its columns, it returns with no result.
run sql select d.name as Device, n.dnorpattern as Number, dhd.hlog as LoggedIn_to_LG, lg.name as LineGroup, e.datetimestamp
from linegroup as lg
inner join linegroupnumplanmap as lgmap on lgmap.fklinegroup=lg.pkid
inner join numplan as n on lgmap.fknumplan = n.pkid
inner join devicenumplanmap as dmap on dmap.fknumplan=n.pkid
inner join device as d on dmap.fkdevice=d.pkid
inner join devicehlogdynamic as dhd on dhd.fkdevice=d.pkid
inner join extensionmobilitydynamic as e on e.fkdevice = d.pkid
order by lg.name

It's not finding any matching rows and hence the INNER JOIN fails to retrieve anything. You must try left join for the new table where there is a possibility to have no matching results. The resultant column will be NULL in this instance.
run sql select d.name as Device, n.dnorpattern as Number, dhd.hlog as LoggedIn_to_LG, lg.name as LineGroup, e.datetimestamp
from linegroup as lg
inner join linegroupnumplanmap as lgmap on lgmap.fklinegroup=lg.pkid
inner join numplan as n on lgmap.fknumplan = n.pkid
inner join devicenumplanmap as dmap on dmap.fknumplan=n.pkid
inner join device as d on dmap.fkdevice=d.pkid
inner join devicehlogdynamic as dhd on dhd.fkdevice=d.pkid
left join extensionmobilitydynamic as e on e.fkdevice = d.pkid
order by lg.name

Related

Unnecessary LEFT JOINs on all Child tables from main LEFT JOIN table required in query for correct result

I am LEFT JOIN-ing the table RECALLS_T with EVENTS_T. Some Recalls do not have any Events, and for those I want a blank row returned.
However, once an entry in EVENTS_T exists, all the following extra tables from EVENTS_T which I also need (ANSWERS_T, ACTIVITY_QUESTIONS_T, ACTIVITES_T) are guaranteed to have entries. For these subsequent tables there is no need to do a LEFT JOIN from their parent, it can be an INNER JOIN just as well.
But if I do the following, the query does not return blank EVENTS_T rows for a RECALLS_T.
SELECT ..
FROM
recalls_t r
LEFT JOIN events_t e ON ( r.id = e.recall_id ) --Only LEFT JOIN this main table
INNER JOIN answers_t ans ON (ans.event_id = e.id)
INNER JOIN activity_questions_t aq ON (ans.activity_question_id = aq.id)
INNER JOIN PUBLIC.activities_t act ON (aq.activity_id = act.id)
Instead, I need to change every subsequent INNER JOIN to a LEFT JOIN as well, in order to get Recalls with blank Events.
SELECT ..
FROM
recalls_t r
LEFT JOIN events_t e ON ( r.id = e.recall_id )
LEFT JOIN answers_t ans ON (ans.event_id = e.id)
LEFT JOIN activity_questions_t aq ON (ans.activity_question_id = aq.id)
LEFT JOIN PUBLIC.activities_t act ON (aq.activity_id = act.id)
I'm just not clear on why I have to do this. The top-level optional join is all I care about, but the downstream joins from EVENTS_T are guaranteed to have data provided the Event exists. Shouldn't the top-level single EVENTS_T join be enough? I'm using Postgres.
The reason you need to do this is because rows preserved by the outer join will have NULL for all columns from events - so inner joining using an equality condition on e.id will remove them from the result again.
you can move the ON clause to the end of the query to give your desired semantics.
The left join is then on the virtual result of inner joining events_t, answers_t, activity_questions_t and activities_t
SELECT ...
FROM recalls_t r
LEFT JOIN events_t e
INNER JOIN answers_t ans
ON ( ans.event_id = e.id )
INNER JOIN activity_questions_t aq
ON ( ans.activity_question_id = aq.id )
INNER JOIN PUBLIC.activities_t act
ON ( aq.activity_id = act.id )
ON ( r.id = e.recall_id )
Or you could consider a RIGHT JOIN here instead
SELECT ...
FROM events_t e
INNER JOIN answers_t ans
ON ( ans.event_id = e.id )
INNER JOIN activity_questions_t aq
ON ( ans.activity_question_id = aq.id )
INNER JOIN PUBLIC.activities_t act
ON ( aq.activity_id = act.id )
RIGHT JOIN recalls_t r
ON ( r.id = e.recall_id )
You have to do this because answers_t`` is joining onevents_s. If thejoinkey (e.recall_id) isNULL`, then there will be no match. And the inner join will not return the row. And so on for the other tables.
You seem to understand the fix. Once you use left join, you need to continue using left join for those tables that are connected to the second table of the left join.

List all donations made, by both individual alumni and business donors. Name, ID of the donor, date and amount of the donation must be displayed

Need help in this problem. I have the following tables but i cannot seem to get any data out based on the description and query as below.
Corporate(CorporateID(PK), CorporateName, CorporateAddress)
Donation(DonationID(PK), TypeOfDonations)
Alumnus(AlumnusID(PK), CityPK(FK), AlumnusName, EmailAddress, WorkPhoneNumber, HomePhoneNumber, Address
Donation_Made(CorporateDonationID(PK), DonationID(FK), CorporateID(FK), AlumnusID(FK), DonationAmount, DateOfDonation
SELECT Z.DONATIONID, A.ALUMNUSNAME, C.CORPORATENAME, Z.DATEOFDONATION, Z.DONATIONAMOUNT
FROM ALUMNUS A,
(SELECT * FROM DONATION D LEFT JOIN DONATION_MADE DM
ON D.DONATIONID = DM.DONATIONID)Z LEFT JOIN CORPORATE C
ON C.CORPORATEID = DM.CORPORATEID AND A.ALUMNUSID=DM.ALUMNUSID AND Z.TYPEOFDONATIONS= 'MONETARY';
You should start with the fact table, i.e. DONATION_MADE, and then (outer) join the related tables:
SELECT DM.DONATIONID,
A.ALUMNUSNAME,
C.CORPORATENAME,
DM.DATEOFDONATION,
DM.DONATIONAMOUNT
FROM DONATION_MADE DM
INNER JOIN DONATION D
ON D.DONATIONID = DM.DONATIONID
LEFT JOIN ALUMNUS A,
ON A.ALUMNUSID = DM.ALUMNUSID
LEFT JOIN CORPORATE C
ON C.CORPORATEID = DM.CORPORATEID
WHERE D.TYPEOFDONATIONS = 'MONETARY';
You need to use outer join to get data from both Corporate and Alumnus tables.
select a.AlumnusID, a.AlumnusName, c.CorporateID, c.CorporateName, dm.DateOfDonation, dm.DonationAmount
from Donation_Made dm
left outer join on Alumnus a on dm.AlumnusID = a.AlumnusID
left outer join on Corporate c on dm.CorporateID = c.CorporateID
inner join on Donation d on dm.DonationID = d.DonationID
where d.TypeOfDonations='MONETARY';

How can I avoid using the NOT IN and the SUBSELECT in the following query

How can I avoid using the NOT IN subselect in this query and also avoid the subselect ?
select idTipoDocumento,idDocumentoTarea
from ArchivosTarea as a
inner join Tarea as b on a.idEstadoTarea=b.idTarea
where b.idTarea = 160
and idDocumentoTarea not in (select idDocumentoTarea
from ArchivosTarea as a
inner join tiposArchivos as b on a.idTipoDocumento = b.idTipoArchivo
inner join documentoSolicitud as c on b.idTipoArchivo = c.Id_tipo_archivo
inner join tarea as d on a.idEstadoTarea=d.idTarea
where d.idTarea = 160)
I know that probably a LEFT JOIN or something like that should do the trick but I have tried that and it does not provide me the same results as this query.
The actual idea is to avoid the SUBSELECT (of the WHERE) and also avoid the NOT IN.
Using left join:
Select A.idTipoDocumento,A.idDocumentoTarea from
(select idTipoDocumento,idDocumentoTarea
from ArchivosTarea as a
inner join Tarea as b on a.idEstadoTarea=b.idTarea
where b.idTarea = 160)A
left outer join
(select idDocumentoTarea from ArchivosTarea as a
inner join tiposArchivos as b on a.idTipoDocumento = b.idTipoArchivo
inner join documentoSolicitud as c on b.idTipoArchivo = c.Id_tipo_archivo
inner join tarea as d on a.idEstadoTarea=d.idTarea
where d.idTarea = 160)B
on A.idDocumentoTarea=B.idDocumentoTarea
where B.idDocumentoTarea is null
It happens that SQL Server has antijoin aka semiminus aka EXCEPTION JOIN. It return rows in the left argument that don't match when joined by the right.
select idTipoDocumento,idDocumentoTarea
from ArchivosTarea as a
inner join Tarea as b on a.idEstadoTarea=b.idTarea
and b.idTarea = 160
exception join (
select idDocumentoTarea
from ArchivosTarea as a
inner join tiposArchivos as b on a.idTipoDocumento = b.idTipoArchivo
inner join documentoSolicitud as c on b.idTipoArchivo = c.Id_tipo_archivo
inner join tarea as d on a.idEstadoTarea=d.idTarea
where d.idTarea = 160)
You can do this with LEFT JOIN. Also using NOT EXISTS.

How to retrieve count of records in SELECT statement

I am trying to retrieve the right count of records to mitigate an issue I am having. The below query returns 327 records from my database:
SELECT DISTINCT COUNT(at.someid) AS CountOfStudentsInTable FROM tblJobSkillAssessment AS at
INNER JOIN tblJobSkills j ON j.jobskillid = at.skillid
LEFT JOIN tblStudentPersonal sp ON sp.someid2 = at.someid
INNER JOIN tblStudentSchool ss ON ss.monsterid = at.someid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
Where I run into trouble is trying to reconcile that with the below query. One is for showing just a count of all the particular students the other is showing pertinent information for a set of students as needed but the total needs to be the same and it is not. The below query return 333 students - the reason is because the school the student goes to is in two separate counties and it counts that student twice. I can't figure out how to fix this.
SELECT DISTINCT #TableName AS TableName, d.district AS LocationName, cty.county AS County, COUNT(DISTINCT cc.monsterid) AS CountOfStudents, d.IRN AS IRN FROM tblJobSkillAssessment AS cc
INNER JOIN tblJobSkills AS c ON c.jobskillid = cc.skillid
INNER JOIN tblStudentPersonal sp ON sp.monsterid = cc.monsterid
INNER JOIN tblStudentSchool ss ON ss.monsterid = cc.monsterid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
GROUP BY cty.county, d.IRN, d.district
ORDER BY LocationName ASC
If you just want the count, then perhaps count(distinct) will solve the problem:
select count(distinct at.someid)
I don't see what at.someid refers to, so perhaps:
select count(distinct cc.monsterid)

Having trouble joining tables

I'm trying to write a query to display the name of each passenger with their fare.
Here's what I have so far -- it gives no errors, but also no results:
-- Write a query to display the Name of each passenger as well as the fare for their trip.
select passenger.name, departure_info.fare * passenger.quantity AS passenger_fare
from passenger, seat_passenger, manages, departure_info, seat_info
where departure_info.Dept_id=manages.Dept_id
AND manages.Seat_id=seat_info.Seat_id
AND seat_info.Seat_id=seat_passenger.Seat_id
AND seat_passenger.Pass_id=passenger.pass_id
Here is the relationship view of the tables http://i.imgur.com/R4EFthY.png
using proper joins syntax will make this query from your query
select
p.name, di.fare * p.quantity as passenger_fare
from passenger as p
inner join seat_passenger as sp on sp.pass_id = p.pass_id
inner join seat_info as si on si.seat_id = sp.seat_id
inner join manages as m on m.seat_id = si.seat_id
inner join departure_info as di on di.dept_it = m.dept_id
I suggest you to turn inner joins into left outer joins and see what you're missing
select
p.name, di.fare * p.quantity as passenger_fare,
sp.pass_id, si.seat_id, m.seat_id, di.dept_id
from passenger as p
left outer join seat_passenger as sp on sp.pass_id = p.pass_id
left outer join seat_info as si on si.seat_id = sp.seat_id
left outer join manages as m on m.seat_id = si.seat_id
left outer join departure_info as di on di.dept_it = m.dept_id
Actually, you could even remove unused joins (if you don't miss some records from seat_info):
select
p.name, di.fare * p.quantity as passenger_fare
from passenger as p
inner join seat_passenger as sp on sp.pass_id = p.pass_id
inner join manages as m on m.seat_id = sp.seat_id
inner join departure_info as di on di.dept_it = m.dept_id