SQL to LINQ to SQL expression without Join - sql

While converting an SQL query below query with navigation in Entity Framework
SELECT DISTINCT
a.ApplicationID, eA.EmployeeID AS AppID, eA.EmailID AS AppEmail,
eA.Title + eA.Name AS Applicant, eR.EmployeeID, eR.Title + eR.Name
AS Employee, eR.EmailID AS Email, r.Title AS Role, r.RoleID, t .Title AS
Task, t .TaskID, d .ShortName AS AppDeptSN, a.Reminders, '' AS SubTaskID
FROM
dbo.Application_TaskLog AS a INNER JOIN
dbo.Task AS t ON t .TaskID = a.TaskID INNER JOIN
dbo.Role AS r ON r.RoleID = t .RoleID INNER JOIN
dbo.Application_Role AS ar ON ar.ApplicationID = a.ApplicationID AND
ar.RoleID = t .RoleID INNER JOIN
dbo.Employee AS eR ON eR.EmployeeID = ar.EmployeeID INNER JOIN
dbo.Application AS app ON app.ApplicationID = a.ApplicationID INNER JOIN
dbo.Employee AS eA ON eA.EmployeeID = app.EmployeeID LEFT OUTER JOIN
dbo.Departments AS d ON eA.DepartmentID = d .DepartmentID
I wrote the following function to populate gridview
public List<Application_TaskLog> GetAppTaskLogDistinct(int appID)
{
var context = new FPSDB_newEntities();
var data = (from atl in context.Application_TaskLog
where atl.ApplicationID == appID
&& !atl.Application.ApplicationClosed && !atl.Completed
select atl).Distinct().ToList();
return data;
}
Distinct() is not working as it works in the SQL. I am confused how to use Distinct as I have used in SQL

context.Application_TaskLog already returns distinct Application_TaskLog records and there's nothing in the query that duplicates them, so Distinct() doesn't make any difference

Related

SQL - merge two queries

I have the two below queries, the first query returns a list of externalId.
select e.externalId
from data_entity db
inner join assign_entity a on db.fk_assign = a.assignmentId
inner join exercise_entity e on a.fk_exercice = e.externalId;
The second query returns an internalId of each externalId returned by the first query:
select me.internal_id
from entity me
inner join entity_roles r on me.externalid = r.entity_externalid
where r.roles = 'c9237a21-f6da-4ebe-81b0-ddecd51da86b';
How can I merge the two queries in a single query to return for each externalId its internalId like this?
This should do what is required I think. Since there is no fiddle/data present, I can not test it.
with external as
(select e.externalId as externalId from data_entity db
inner join assign_entity a on db.fk_assign = a.assignmentId
inner join exercise_entity e on a.fk_exercice = e.externalId)
select distinct e.externalId, me.internal_id from entity me
inner join entity_roles r on me.externalid = r.entity_externalid
inner join external e on r.roles = e.externalId;
You can use EXISTS:
select me.internal_id, me.externalId
from entity me
inner join entity_roles r on me.externalid = r.entity_externalid
WHERE r.roles = 'c9237a21-f6da-4ebe-81b0-ddecd51da86b'
and exists (
select * from data_entity db
inner join assign_entity a on db.fk_assign = a.assignmentId
inner join exercise_entity e on a.fk_exercice = e.externalId
where e.externalId = me.externalId
);
Probably this query is simpler than what it is now, but based only on your pictures and queries this would do.
PS: Next time, please provide a good sample of your data tables. Pictures do not help much to anyone.
Without some data or a fiddle it is difficult to help, but I think this should work:
SELECT me.internal_id,
me.externalid
FROM entity me
INNER JOIN entity_roles r
ON me.externalid = r.entity_externalid
WHERE r.roles = 'c9237a21-f6da-4ebe-81b0-ddecd51da86b'
AND EXISTS (SELECT *
FROM data_entity db
INNER JOIN exercise_entity e
ON a.fk_exercice = e.externalid
INNER JOIN assign_entity a
ON db.fk_assign = a.assignmentid
WHERE me.externalid = e.externalid);

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)

Why query with MAX(Date) dosen't return any record?

I have a sql query like below:
SELECT CPH.CheckPointID,
CPH.ID AS Check_Point_History_ID,
CLCP.SequenceNo AS Sequence,
CP.Code AS Point_Code,
CPV.ID,
TT.Medium AS Description,
[TEXT_TRANSLATION_ANS].[Medium] AS Value,
CPH.Value_ AS Additional_Information,
EMP.NAME AS Checked_By,
CPH.AnsweredOn AS Checked_On
FROM CHECK_LIST_HISTORY CLH
LEFT JOIN CHECK_POINT_HISTORY CPH
ON CLH.ID = CPH.CheckListHistoryID
INNER JOIN (
SELECT CPH2.CheckPointID,
MAX(CPH2.AnsweredOn) AS MaxDate
FROM CHECK_LIST_HISTORY CLH2
LEFT JOIN CHECK_POINT_HISTORY CPH2
ON CLH2.ID = CPH2.CheckListHistoryID
GROUP BY CPH2.CheckPointID
) tm
ON CPH.CheckPointID = tm.CheckPointID
AND CPH.AnsweredOn = tm.MaxDate
LEFT JOIN CHECK_POINT CP
ON CPH.CheckPointID = CP.ID
LEFT JOIN CHECK_POINT_VALUE CPV
ON CPH.CheckPointValueID = CPV.ID
LEFT JOIN TEXT_TRANSLATION TT
ON CP.TextID = TT.TextID
AND TT.LanguageID = LanguageID
LEFT JOIN CHECK_LIST_CHECK_POINT CLCP
ON CP.ID = CLCP.CheckPointID
LEFT JOIN EMPLOYEE EMP
ON CPH.EmployeeID = EMP.ID
LEFT JOIN [TEXT_TRANSLATION] [TEXT_TRANSLATION_ANS]
ON CPV.AnswerTextID = [TEXT_TRANSLATION_ANS].[TextID]
AND [TEXT_TRANSLATION_ANS].[LanguageID] = TT.LanguageID
LEFT JOIN [TEXT_TRANSLATION] [TEXT_TRANSLATION_RES]
ON CPV.ResponseTextID = [TEXT_TRANSLATION_RES].[TextID]
AND [TEXT_TRANSLATION_RES].[LanguageID] = TT.LanguageID
WHERE CLH.WipOrderNo = 304
AND CLH.WipOrderType = 26
AND CLCP.WorkCenter = 'WC03'
AND CLCP.Facility = 'C1P1'
This query should return me two records with maximum date, but it returns nothing. I think the problem is in the INNER JOIN because when the line with the INNER JOIN is commented, the query returns the following table:

How can I remove a sub-query from a NOT EXISTS contained in an INNER JOIN?

Due to rules set forward by third party software I need to remove the sub-query from the following code:
SELECT
1
FROM
factAttempt fact
INNER JOIN dimActivity act ON act.ID = fact.ActivityID
INNER JOIN dimUser emp ON emp.ID = fact.UserID
INNER JOIN Iwc_Usr IUser ON IUser.Usr_empFK = emp.EmpFK
INNER JOIN dimActivity class ON (
(class.ActivityFK = act.PrntActFK)
OR (
NOT EXISTS (
SELECT 1
FROM TBL_TMX_activity act1
WHERE act1.PrntActFK = Class.ActivityFK
)
AND
Class.ActivityFK = act.ActivityFK
)
)
AND class.ActivityName = act.ActivityName
I have tried using a Boolean (bit) scalar variable to replace it but while it will run the wrong results are returned. Since I don't know too much SQL I haven't been able to find anything else yet.
I'm using Microsoft SQL Server 2012 if that's useful
Thanks for the help.
You can move the exists table to a left join. Then the equivalent to the not exists is checking that the value of a field in the right part of the join is null.
SELECT
1
FROM
factAttempt fact
INNER JOIN dimActivity act ON act.ID = fact.ActivityID
INNER JOIN dimUser emp ON emp.ID = fact.UserID
INNER JOIN Iwc_Usr IUser ON IUser.Usr_empFK = emp.EmpFK
INNER JOIN dimActivity class
LEFT JOIN TBL_TMX_activity act1
ON act1.PrntActFK = class.ActivityFK
ON
(
(
class.ActivityFK = act.PrntActFK
OR
(act1.PrntActFK IS NULL -- equivalent of NOT EXISTS
AND Class.ActivityFK = act.ActivityFK)
)
AND class.ActivityName = act.ActivityName
)

Add a filter parameter to ssrs report

I have a query that I need to update to allow user to filter out pending applications. I have created the parameter and tried to implement using case but it is not working or giving any error messages on how to correct it. The code is:
select distinct pers.person_fname,
pers.person_mname,
pers.person_lname,
le.nationalprovidernumber NPN,
lic.licensenumber LICENSE_NUMBER,
adr.address_line1 ADDRESS1,
adr.address_line2 ADDRESS2,
adr.address_line3 ADDRESS3,
adr.city CITY,
sp.state_province_name STATE,
adr.postal_code ZIP_CODE,
eml.email,
rtp.residencetype_name RESIDENCY,
ltp.licensetype_name LICENSE_TYPE,
lic.expirationdate DATE_OF_EXPIRATION
from odilic_admin.license lic
inner join odilic_admin.licenseststimeline lst
on lic.license_id = lst.license_id
inner join odilic_admin.licenseststype lstp
on lst.licenseststype_id = lstp.licenseststype_id
inner join odilic_admin.licensedef ldef
on lic.licensedef_id = ldef.licensedef_id
inner join odilic_admin.licensetype ltp
on ldef.licensetype_id = ltp.licensetype_id
inner join odilic_admin.residencetype rtp
on ldef.residencetype_id = rtp.residencetype_id
inner join odilic_admin.licensingentity le
on lic.licensingentity_id = le.licensingentity_id
inner join odilic_admin.individual ind
on le.licensingentity_id = ind.licensingentity_id
inner join odidir_admin.person pers
on ind.person_id = pers.person_id
left outer join odidir_admin.person_address_rel par
on pers.person_id = par.person_id
left outer join odidir_admin.address adr
on par.address_id = adr.address_id
left outer join odidir_admin.address_type atp
on adr.address_type_id = atp.address_type_id
left outer join odidir_admin.state_province sp
on adr.state_province_id = sp.state_province_id
left outer join
(select pr.person_id, em.email_id, em.email
from odidir_admin.person pr,
odidir_admin.person_email_rel pe,
odidir_admin.email em
where pr.person_id = pe.person_id
and pe.email_id = em.email_id
and email_type_id = 2) eml
on pers.person_id = eml.person_id
where
ltp.licensetype_id in (:License_type)
and lstp.licenseststype_name = 'Active'
and atp.address_type_name = 'Mailing Licensing'
and (lic.expirationdate >= current_date and
trunc(lic.expirationdate) = :Expiration_Date)
and sysdate between lst.periodbegindate and lst.periodenddate
order by lic.licensenumber
In order to get applications that are pending I need to access the table odilic_admin.licenseappl and filter out all licenses with appststype = 2 (pending). To do this I added a join to the query before the last left outer join andt hen a case at bottom for when this parameter is selected.
select distinct pers.person_fname,
pers.person_mname,
pers.person_lname,
le.nationalprovidernumber NPN,
lic.licensenumber LICENSE_NUMBER,
adr.address_line1 ADDRESS1,
adr.address_line2 ADDRESS2,
adr.address_line3 ADDRESS3,
adr.city CITY,
sp.state_province_name STATE,
adr.postal_code ZIP_CODE,
eml.email,
rtp.residencetype_name RESIDENCY,
ltp.licensetype_name LICENSE_TYPE,
lic.expirationdate DATE_OF_EXPIRATION
from odilic_admin.license lic
inner join odilic_admin.licenseststimeline lst
on lic.license_id = lst.license_id
inner join odilic_admin.licenseststype lstp
on lst.licenseststype_id = lstp.licenseststype_id
inner join odilic_admin.licensedef ldef
on lic.licensedef_id = ldef.licensedef_id
inner join odilic_admin.licensetype ltp
on ldef.licensetype_id = ltp.licensetype_id
inner join odilic_admin.residencetype rtp
on ldef.residencetype_id = rtp.residencetype_id
inner join odilic_admin.licensingentity le
on lic.licensingentity_id = le.licensingentity_id
inner join odilic_admin.individual ind
on le.licensingentity_id = ind.licensingentity_id
inner join odidir_admin.person pers
on ind.person_id = pers.person_id
left outer join odidir_admin.person_address_rel par
on pers.person_id = par.person_id
left outer join odidir_admin.address adr
on par.address_id = adr.address_id
left outer join odidir_admin.address_type atp
on adr.address_type_id = atp.address_type_id
left outer join odidir_admin.state_province sp
on adr.state_province_id = sp.state_province_id
**left outer join odilic_admin.licenseappl appl
on lic.licensingentity_id = appl.licenseappl_id**
left outer join
(select pr.person_id, em.email_id, em.email
from odidir_admin.person pr,
odidir_admin.person_email_rel pe,
odidir_admin.email em
where pr.person_id = pe.person_id
and pe.email_id = em.email_id
and email_type_id = 2) eml
on pers.person_id = eml.person_id
where
ltp.licensetype_id in (:License_type)
and lstp.licenseststype_name = 'Active'
and atp.address_type_name = 'Mailing Licensing'
and (lic.expirationdate >= current_date and
trunc(lic.expirationdate) = :Expiration_Date)
and sysdate between lst.periodbegindate and lst.periodenddate
**case :pending when = yes then appl.applststype_id !=2
end**
order by lic.licensenumber
Instead of the case I have also tried using an IF with the same result. This looks like:
if :Pending = 1
then
and appl.applststype_id != 2;
end if;
Any help to get me past this is greatly appreciated and I will be sure to vote and select most correct answer to help me solve this.
Assuming that your :pending parameter is a numeric where a value of 1 indicates that pending licences are to be excluded and you only want to exclude licence applications that are pending, try adding the following condition in place of your existing case clause:
and (:pending <> 1 or appl.applststype_id !=2)