I have a little question, why if I do a Query on table SecurityRole with join other table, when i get the value from field SecurityRole.Name I have only the Label (look like #SYS...) and I have to convert.
SecurityRole securityRole;
SecurityUserRole UserRole;
SysUserInfo userInfo;
OMUserRoleOrganization roleOrganization;
OMInternalOrganization internalOrganization;
while select ID from userInfo
order by id asc
outer join UserRole
where UserRole.User == userInfo.Id
outer join securityRole
where securityRole.RecId == UserRole.SecurityRole
outer join roleOrganization
where roleOrganization.User == userInfo.Id
&& roleOrganization.SecurityRole == UserRole.SecurityRole
outer join internalOrganization
where internalOrganization.RecId == roleOrganization.OMInternalOrganization
{
print userInfo.Id, userInfo.Email, SysLabel::labelId2String(securityRole.Name), internalOrganization.Name ? internalOrganization.Name : "All Company";
pause;
}
If I do a simple Query like this :
while select securityRole
{
info (strfmt("%1", securityRole.Name)); // here I have the really value filed - NOT the label
}
So, my question is this : why if I do a query on securityRole with join I will have a label from field Name.
I know, there is a way to get the value from label (SysLabel::labelId2String2(. .. )) , but for me it's better to get the really value from Table's field.
There is a way to get always the really field value (That shown in Table)?
Thanks,
enjoy!
If you explicitly specify the field list in your select clause, you'll get the name of the role, not the label:
outer join Name from securityRole
instead of
outer join securityRole
Related
I am working on sql server I have two tables and I need to return records from the left table which are not found in the right table for that I am using left join like below query,
select #MID=MID,#MName=Name,#PID=PID,#PName=PName,#DID=DID from #CompanyDataInfo where id=#MCount
insert into #temp SELECT Top(1) f.Name,f.PID,f.PName,v.* FROM #CompanyDataInfo f
left join Employee v on v.Id=f.ID and v.DID=f.DID
where v.Id =#MID and v.DId = #DId and v.PId = #PId and v.CId =#CId and DATE_TIME between DATEADD(minute,-555,GETDATE()) and GETDATE() order by DATE_TIME desc
Result should be all rows from #CompanyDataInfo table while no record found in Employee table for related ID, I googled and use "v.Id is null" but not getting expected result
Is there any solution greatly appriciable
Thanks In advance
Your query is not using left join in correct way. You are using your right table reference in where clause. I try to correct it below but I don't have full information about your table schema. Please try this-
select
#MID = MID,
#MName = Name,
#PID = PID,
#PName = PName,
#DID = DID
from #CompanyDataInfo
where id = #MCount
insert into #temp
select
f.Name,
f.PID,
f.PName,
v.*
from #CompanyDataInfo f
left join Employee v on v.Id=f.ID and v.DID=f.DID
where f.Id = #MID and
f.DId = #DId and
f.PId = #PId and
f.CId = #CId and
f.DATE_TIME between DATEADD(minute,-555,GETDATE()) and GETDATE() and
v.Id is null
order by f.DATE_TIME desc
Add ...and v.Id is null to your where clause.
Lets Say a domain class A has many Class B objects. I need to do a criteria query which returns
A.id
A.name
B.count(no of B elements associated with A)
B.last Updated(date of most recent update of B elements associated with A considering i have last_updated date for all B elements)
Also the query should be flexible enough to add conditions/restrictions to both A and B domain objects.
Currently I have gotten as far as this:
A.createCriteria().list {
createAlias('b','b')
projections{
property('id')
property('gender')
property('dateOfBirth')
count('b.id')
property('publicId')
}
}
But the problem is that it only returns one object and the count of child objects is for all the elements of B instead of just those associated with A
Recently I was in a similar scenario I needed a query in which one of your rows will store the count of many in a one-to-many relationship
But unlike your scenario I used native sql queries to resolve the query.
The solution was to use derived tables (I do not know how to implement them using criteria query).
In case you find it useful I share a code with the implementation taken from a grails service:
List<Map> resumeInMonth(final String monthName) {
final session = sessionFactory.currentSession
final String query = """
SELECT
t.id AS id,
e.full_name AS fullName,
t.subject AS issue,
CASE t.status
WHEN 'open' THEN 'open'
WHEN 'pending' THEN 'In progress'
WHEN 'closed' THEN 'closed'
END AS status,
CASE t.scheduled
WHEN TRUE THEN 'scheduled'
WHEN FALSE THEN 'non-scheduled'
END AS scheduled,
ifnull(d.name, '') AS device,
DATE(t.date_created) AS dateCreated,
DATE(t.last_updated) AS lastUpdated,
IFNULL(total_tasks, 0) AS tasks
FROM
tickets t
INNER JOIN
employees e ON t.employee_id = e.id
LEFT JOIN
devices d ON d.id = t.device_id
LEFT JOIN
(SELECT
ticket_id, COUNT(1) AS total_tasks
FROM
tasks
GROUP BY ticket_id) ta ON t.id = ta.ticket_id
WHERE
MONTHNAME(t.date_created) = :monthName
ORDER BY dateCreated DESC"""
final sqlQuery = session.createSQLQuery(query)
final results = sqlQuery.with {
resultTransformer = AliasToEntityMapResultTransformer.INSTANCE
setString('monthName', monthName)
list()
}
results
}
The part of interest is to declare a row within the main select and then in the clause from declare the derived query that stores the result in a row with the same name declared in the main select
SELECT ...
total_tasks --Add the count column to your select
FROM ticket t
JOIN (SELECT ticked_id, COUNT(1) as total_tasks
FROM tasks
GROUP BY ticked_id) ta ON t.id = ta.ticked_id
...rest of query
This last example I share from the answer made by the user Aaron Dietz to the question that I also formulate
I hope it is useful for you
Turns out I wasn't very far from the solution and i just needed to do grouping based on the right property which is the foreign key column in the child table which is b.a in this case so the following works now
A.createCriteria().list {
createAlias('b','b')
projections{
property('id')
property('gender')
property('dateOfBirth')
count('b.id')
groupProperty('b.a')
property('publicId')
}
}
In the criteria you need to group by the property which are not aggregate.
Try following:
A.createCriteria().list {
createAlias('b','b')
projections{
groupProperty('id','id')
groupProperty('gender','gender')
groupProperty('dateOfBirth','dateOfBirth')
count('b.id','total')
groupProperty('publicId','publicId')
}
}
or If you want to have a list of map object return you can try add resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
A.createCriteria().list {
resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
createAlias('b','b')
projections{
groupProperty('id','id')
groupProperty('gender','gender')
groupProperty('dateOfBirth','dateOfBirth')
count('b.id','total')
groupProperty('publicId','publicId')
}
}
Hope it can help
I have a 'Skill' table where i store skills. And in 'Job' table i store all required skill when post job like UpWork. Employeers have checkbox to select all required skills. But i store skillID like: 1,5,6,8 in job table. When i retrieve the job details, i want to get name of the all skills because i want to show SkillName with other details of the Job from job table. My Web Api:
[HttpGet]
[Route("api/JobApi/BrowseJobs/")]
public object BrowseJobs()
{
var skills = db.Skills.ToDictionary(d => d.SkillID, n => n.SkillName);
var jobData = (from j in db.Jobs where j.Preference==2
//from cj in j.ClosedJobs.DefaultIfEmpty()
join cj in db.ClosedJobs.DefaultIfEmpty()
on j.JobID equals cj.JobID into closedJob
where !closedJob.Any()
join c in db.Categories on j.Category equals c.CategoryID
join jobContract in
(
from appliedJob in db.AppliedJobs.DefaultIfEmpty()
from offer in appliedJob.JobOffers.DefaultIfEmpty()
from contract in db.Contracts.DefaultIfEmpty()
select new { appliedJob, offer, contract }
).DefaultIfEmpty()
on j.JobID equals jobContract.appliedJob.JobID into jobContracts
where !jobContracts.Any(jobContract => jobContract.contract.CompletedDate != null)
select new
{
JobTitle = j.JobTitle,
JobID = j.JobID,
ReqSkillCommaSeperated = j.ReqSkill,
Category = c.CategoryName,
Budget=j.Budget,
Deadline=j.Deadline,
JobDetails=j.JobDetails,
PublishDate=j.PublishDate,
TotalApplied=(from ap in db.AppliedJobs where j.JobID == ap.JobID select ap.AppliedJobID).DefaultIfEmpty().Count()
}).AsEnumerable()
.Select(x => new
{
JobID = x.JobID,
JobTitle = x.JobTitle,
Category = x.Category,
Budget = x.Budget,
Deadline = x.Deadline,
JobDetails = x.JobDetails,
PublishDate = x.PublishDate,
SkillNames = GetSkillName(x.ReqSkillCommaSeperated, skills),
TotalApplied = (from ap in db.AppliedJobs where x.JobID == ap.JobID select ap.AppliedJobID).DefaultIfEmpty().Count()
}).ToList();
return jobData.AsEnumerable();
}
private string GetSkillName(string reqSkill, Dictionary<int, string> skills)
{
if (reqSkill == null) return string.Empty;
var skillArr = reqSkill.Split(',');
var skillNameList = skillArr.Select(skillId => skills[Convert.ToInt32(skillId)])
.ToList();
return String.Join(",", skillNameList);
}
My Problem is that the code is working well in my VS 2013. But when i uploaded it on a Godaddy live server, it doesn't work! returns 500 internal server error
Now i want to Make a SQL query instead of Linq. Can i do SQL with my desired result?
===================Edited=====================
your sql code is well worked. But i have others condition to be put on.
1. I need to show those job which is not closed yet (ClosedJobs table take the closed jobs ID).If a job ID is found on ClosedJobs table, it will not return in the list.
join cj in db.ClosedJobs.DefaultIfEmpty()
on j.JobID equals cj.JobID into closedJob
where !closedJob.Any()
Those job which is not found on Contracts table(Contracts table take the jobID of a job that is started as contract)
2nd Edit===================
join jobContract in
(
from appliedJob in db.AppliedJobs.DefaultIfEmpty()
from offer in appliedJob.JobOffers.DefaultIfEmpty()
from contract in db.Contracts.DefaultIfEmpty()
select new { appliedJob, offer, contract }
).DefaultIfEmpty()
on j.JobID equals jobContract.appliedJob.JobID into jobContracts
where !jobContracts.Any(jobContract => jobContract.contract.CompletedDate != null)
EXP: Job table has relation with AppliedJobs table. AppliedJobs table has relation with JobOffers. JobOffers has relation with Contracts.
i don't want to show those jobs that are completed.(Contracts.CompletedDate != null). When a contract starts the field CompletedDate is set to null. After completing the contract ,it is changed null to the completed date.
Where i will apply the condition?
How can i do that? Can you help me? #John Cappelletti
EDIT - Removed OUTER APPLY
Below is a simple example of using Stuff() and XML. If the sequence is important, then we must split the string first.
To be clear #Skills and #YourData are table variables and simply demonstrative.
Example
Declare #Skills table (SkillID int,SkillName varchar(50))
Insert Into #Skills values
(1,'ASP')
,(2,'JavaScript')
,(3,'AngularJS')
,(4,'WordPress')
,(5,'Joomla')
Declare #YourData table (ID int,ReqSkill varchar(50))
Insert Into #YourData values
(1,'2,3,4,5,1')
,(2,'3')
,(3,'3,4,5,2')
,(4,null)
Select A.ID
,Skills = Stuff((Select ',' +SkillName
From #Skills
Where charindex(concat(',',SkillID,','),','+A.ReqSkill+',')>0
For XML Path ('')),1,1,'')
From #YourData A
-- Your WHERE Statement Here --
Returns
ID Skills
1 ASP,JavaScript,AngularJS,WordPress,Joomla
2 AngularJS
3 JavaScript,AngularJS,WordPress,Joomla
4 NULL
Excuse my english (is not my native language)
Well, i wanna make this query (i make the temp table EMPL, the first temp table VEN is very easy but i don't see how to make the join)
SELECT 'CADORE_MP',EMPL.PERSONNELNUMBER, EMPL.NOMBRE, 0 AS CANTIDAD, VEN.MONTO FROM
(
SELECT VATNUM, SUM(INVOICEAMOUNT) AS MONTO FROM CUSTINVOICEJOUR
WHERE INVOICEDATE>=#FECHAI and INVOICEDATE<=#FECHAF
AND PAYMENT LIKE '%DIAS%'
AND CUSTGROUP LIKE 'EMP%'
AND REVERSE_GT=0 AND TAXTYPEDOCUMENTID='FC'
GROUP BY VATNUM) VEN
INNER JOIN
(
SELECT HW.PERSONNELNUMBER, HPIN.IDENTIFICATIONNUMBER, PRE.FIRSTNAME+' '+PRE.SECONDNAME+' '+PRE.FIRSTLASTNAME+' '+PRE.SECONDLASTNAME AS NOMBRE
FROM HcmPersonIdentificationNumber HPIN INNER JOIN HCMWORKER HW ON HPIN.PERSON=HW.PERSON AND HPIN.IDENTIFICATIONTYPE=5637146829
INNER JOIN PAYROLLEMPL PRE ON HW.PERSON=PRE.PERSON
INNER JOIN HCMEMPLOYMENT HE ON HW.RECID=HE.WORKER
LEFT JOIN PAYROLLLIQUIDATION PL ON HW.PERSONNELNUMBER=PL.EMPLID AND PL.DATELOW<#FECHAF
LEFT JOIN PAYROLLGROUPEMPLOYEES PRGE ON HW.PERSONNELNUMBER=PRGE.EMPLID AND GROUPSEMPLYEESID='CADORE_PQ'
WHERE HE.VALIDTO>='21541231' AND PL.EMPLID IS NULL AND PRGE.EMPLID IS NULL) EMPL ON VEN.VATNUM=EMPL.IDENTIFICATIONNUMBER
it have some parameters and other are constants.
so, i can do the two inner selects but later i can't do the join of this two temp tables
and i wanna know if someone can explain me the diference of join, exists join, no exists join. something like this
and if is posible to make when only wanna data from A but do not intersect with B
This is what i have
Query query;
QueryRun Run;
QueryBuildDataSource dataSourceHW;
QueryBuildDataSource dataSourceHPIN;
QueryBuildDataSource dataSourcePRE;
QueryBuildDataSource dataSourceHE;
QueryBuildDataSource dataSourcePL;
QueryBuildDataSource dataSourcePRGE;
str textDesc = "";
date FechaF;
FechaF = str2Date('21/03/2016',123);
query = new Query();
dataSourceHW = query.addDataSource(tableNum(HcmWorker));
dataSourceHPIN = dataSourceHW.addDataSource(tableNum(HcmPersonIdentificationNumber));
dataSourceHPIN.addLink(fieldNum(HcmWorker, Person), fieldNum(HcmPersonIdentificationNumber, Person));
dataSourceHPIN.addRange(fieldnum(HcmPersonIdentificationNumber,IdentificationType)).value('5637146829');
dataSourceHPIN.fetchMode(QueryFetchMode::One2One);
dataSourceHPIN.joinMode(JoinMode::InnerJoin);
dataSourcePRE = dataSourceHW.addDataSource(tableNum(PayRollEmpl), "PayRollEmpl");
dataSourcePRE.addLink(fieldNum(HcmWorker, Person), fieldNum(PayRollEmpl, Person));
dataSourcePRE.fetchMode(QueryFetchMode::One2One);
dataSourcePRE.joinMode(JoinMode::InnerJoin);
dataSourceHE = dataSourceHW.addDataSource(tableNum(HcmEmployment), "HcmEmployment");
dataSourceHE.addLink(fieldNum(HcmWorker, RecId), fieldNum(HcmEmployment, Worker));
dataSourceHE.addRange(fieldnum(HcmEmployment,ValidTo)).value(strFmt('%1' ,DateTimeUtil::maxValue()));
dataSourceHE.fetchMode(QueryFetchMode::One2One);
dataSourceHE.joinMode(JoinMode::InnerJoin);
dataSourcePL = dataSourceHW.addDataSource(tableNum(PayRollLiquidation));
dataSourcePL.addLink(fieldNum(HcmWorker, PersonnelNumber), fieldNum(PayRollLiquidation, EmplId));
dataSourcePL.addRange(fieldnum(PayRollLiquidation,DateLow)).value('21/03/2016');
dataSourcePL.fetchMode(QueryFetchMode::One2One);
dataSourcePL.joinMode(JoinMode::OuterJoin);
// this join under this dont work, indistinctly if i use it, always show me the same
// because of this i ask above about the data of table A only
dataSourcePRGE = dataSourceHW.addDataSource(tableNum(PayRollGroupEmployees));
dataSourcePRGE.addLink(fieldNum(HcmWorker, PersonnelNumber), fieldNum(PayRollGroupEmployees, EmplId));
dataSourcePRGE.addRange(fieldnum(PayRollGroupEmployees,GroupsEmplyeesId)).value('CADORE_PQ');
//dataSourcePRGE.addRange(fieldnum(PayRollGroupEmployees,EmplId)).value(SysQuery::valueEmptyString());
dataSourcePRGE.fetchMode(QueryFetchMode::One2One);
dataSourcePRGE.joinMode(JoinMode::NoExistsJoin);
will thanks you if someone help me
Using the technique found on the MSDN article "How to: Perform Left Outer Joins (C# Programming Guide)", I attempted to create a left outer join in my Linq code. The article mentions using the DefaultIfEmpty method in order to create a left outer join from a group join. Basically, it instructs the program to include the results of the left (first) collection even if there are no results in the right collection.
The way this program executes, however, it does so as if the outer join has not been specified.
In our database, AgentProductTraining is a collection of courses our agents have taken. Normally you cannot enter a Course onto it's appropriate table without entering a corresponding value into the CourseMaterials table. However, occasionally this may happen, so we want to make sure we return results even when a Course is listed in AgentProductTraining without any corresponding information in CourseMaterials.
var training = from a in db.AgentProductTraining
join m in db.CourseMaterials on a.CourseCode equals m.CourseCode into apm
where
a.SymNumber == id
from m in apm.DefaultIfEmpty()
where m.EffectiveDate <= a.DateTaken
&& ((m.TerminationDate > a.DateTaken) | (m.TerminationDate == null))
select new
{
a.AgentProdTrainId,
a.CourseCode,
a.Course.CourseDescription,
a.Course.Partner,
a.DateTaken,
a.DateExpired,
a.LastChangeOperator,
a.LastChangeDate,
a.ProductCode,
a.Product.ProductDescription,
m.MaterialId,
m.Description,
a.Method
};
The MSDN example uses a new variable subpet:
var query = from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj.DefaultIfEmpty()
select new { person.FirstName, PetName = (subpet == null ? String.Empty : subpet.Name) };
So you must use your own "subpet", I rewrote your code using the submat variable:
var training = from a in db.AgentProductTraining
join m in db.CourseMaterials on a.CourseCode equals m.CourseCode into apm
where
a.SymNumber == id
from submat in apm.DefaultIfEmpty()
where
(submat.EffectiveDate <= a.DateTaken || submat.EffectiveDate == null) &&
(submat.TerminationDate > a.DateTaken || submat.TerminationDate == null)
select new
{
a.AgentProdTrainId,
a.CourseCode,
a.Course.CourseDescription,
a.Course.Partner,
a.DateTaken,
a.DateExpired,
a.LastChangeOperator,
a.LastChangeDate,
a.ProductCode,
a.Product.ProductDescription,
MaterialId = (submat==null?-1:submat.MaterialId),
Description = (submat==null?String.Empty:submat.Description),
a.Method
};