my current query is:
public function teachers_manage() {
$this->db->select('users.user_id, teacher_id, COUNT(student_id) AS S, COUNT(DISTINCT(users.class)) AS C, schools.region, schools.school_name');
$this->db->from('teacher_student_conn');
$this->db->join('users', 'teacher_student_conn.student_id=users.user_id','left');
$this->db->join('schools', 'schools.school_id=users.school_id');
$this->db->where('users.deactivated_at = "0000-00-00 00:00:00" OR users.deactivated_at IS NULL ');
$this->db->where('users.role_id', '1');
$this->db->group_by("teacher_student_conn.teacher_id");
$result=$this->db->get();
return $result->result();
}
It shows me teachers and for each teacher number of classes he teaches and number of students he teaches. I have made join 2 tables - users and teacher_student_conn by users=user_id=teacher_student_conn.student_id and I've put where clause for student not to be deactivated - shows active students. But how to do that also fot the teachers? Another join will change the results. I only want to add where clause for teachers to be active.
My tables look like this:
users
user_id
school_id
class
role_id
created_at
deactivated_at
teacher-student_conn
id
teacher_id
student_id
created_at
I suggest to add a column for "status" to more easily distinguish the status of student and teacher.
And this is my recommended query
SQL Query:
select
from users a
join teacher-student_conn b on a.user_id = b.student_id
join schools c on c.school_id = a.school_id
where (a.status = "Deactivated") and (b.status = "Deactivated")
For codeigniter:
$this->db->select('a.user_id, b.teacher_id, COUNT(b.student_id) AS S, COUNT(DISTINCT(a.class)) AS C, c.region, c.school_name');
$this->db->join('teacher_student_conn b', 'b.student_id = a.user_id','left');
$this->db->join('schools c', 'c.school_id = a.school_id');
$this->db->where('a.status = "Deactivated" or b.status = "Deactivated" ');
$this->db->where('a.role_id', '1');
$this->db->group_by("b.teacher_id");
$result=$this->db->get("users a");
return $result->result();
Related
Hi guys,
I'm currently trying to join two objects in a same query or result.
My question is if it's possible to show or debug the sum of FIELD A FROM LEAD + sum of FIELD B FROM two different Objects.
Here's an example I'm working on:
Btw I really appreciate your time and comments, and if i'm making a mistake pls let me know, thank you.
public static void example() {
String sQueryOne;
String sQueryTwo;
AggregateResult[] objOne;
AggregateResult[] objTwo;
//I tried to save the following querys into a sObject List
List<SObject> bothObjects = new List<SObject>();
sQueryOne = 'Select Count(Id) records, Sum(FieldA) fieldNA From Lead';
objOne = Database.query(sQueryOne);
sQueryTwo = 'Select Count(Id) records, Sum(FieldA) fieldNB From Opportunity';
objTwo = Database.query(sQueryTwo);
bothObjects.addAll(objOne);
bothObjects.addAll(objTwo);
for(sObject totalRec : bothObjects) {
//There's a Wrapper(className) I created which contains some variables(totalSum)
className finalRes = new className();
finalRes.totalSum = (Integer.valueOf(fieldNA)) + (Integer.valueOf(fieldNB));
System.debug('The sum is: '+finalRes.totalSum);
For example if I call a System debug with the previous variable finalRes.totalSum it's just showing the first value(fieldNA) duplicated.
The following debug shows the current values of the sObject List which I want to sum for example FIELD0 = from leads, FIELD0 = from Opportunities.
}
}
You access the columns in AggregateResult by calling get('columnAlias'). If you didn't specify an alias they'll be autonumbered by SF as expr0, expr1... When in doubt you can always go System.debug(results);
Some more info: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_agg_fns.htm
This might give you some ideas:
List<AggregateResult> results = new List<AggregateResult>{
[SELECT COUNT(Id) records, SUM(NumberOfEmployees) fieldA, SUM(AnnualRevenue) fieldB FROM Account],
[SELECT COUNT(Id) records, SUM(Amount) fieldA, SUM(TotalOpportunityQuantity) fieldB FROM Opportunity],
[SELECT COUNT(Id) records, SUM(NumberOfEmployees) fieldA, SUM(AnnualRevenue) fieldB FROM Lead]
/* hey, not my fault these are only 2 standard numeric fields on Lead.
It doesn't matter that they're identical to Account fields, what matters is what their SUM(...) aliases are
*/
};
List<Decimal> totals = new List<Decimal>{0,0,0};
for(AggregateResult ar : results){
totals[0] += (Decimal) ar.get('records');
totals[1] += (Decimal) ar.get('fieldA');
totals[2] += (Decimal) ar.get('fieldB');
}
System.debug(totals); // (636, 8875206.0, 9819762558.0) in my dev org
(I'm not saying it's perfect, your wrapper class sounds like better idea or maybe even Map<String, Decimal>. Depends what are you going to do with the results)
I have a document of type 'User' as-
{
"id":"User-1",
"Name": "Kevin",
"Gender":"M",
"Statuses":[
{
"Status":"ONLINE",
"StatusChangedDate":"2017-11-01T17:12:00Z"
},
{
"Status":"OFFLINE",
"StatusChangedDate":"2017-11-02T13:24:00Z"
},
{
"Status":"ONLINE",
"StatusChangedDate":"2017-11-02T14:35:00Z"
},
{
"Status":"OFFLINE",
"StatusChangedDate":"2017-11-02T15:47:00Z"
}.....
],
"type":"User"
}
I need user's information along with his latest status details based on a particular date (or date range).
I am able to achieve this using subquery and Unnest clause.
Select U.Name, U.Gender, S.Status, S.StatusChangedDate
From (Select U1.id, max(U1.StatusChangedDate) as StatusChangedDate
From UserInformation U1
Unnest Statuses S1
Where U1.type = 'User'
And U1.StatusChangedDate between '2017-11-02T08:00:00Z' And '2017-11-02T11:00:00Z'
And U1.Status = 'ONLINE'
Group by U1.id
) A
Join UserInformation U On Keys A.id
Unnest U.Statuses S
Where U.StatusChangedDate = A.StatusChangedDate;
But is there any other way of achieving this (like by using collection operators and array functions)??
If yes, please provide me a query or guide me through it.
Thanks.
MAX, MIN argument allows array. 0th element of array can be field needs aggregate and 1st element is what you want to carry.
Using this techinuqe you can project non aggregtae field for MIN/MAX like below.
SELECT U.Name, U.Gender, S.Status, S.StatusChangedDate
FROM UserInformation U1
UNNEST Statuses S1
WHERE U1.type = 'User'
AND S1.StatusChangedDate BETWEEN '2017-11-02T08:00:00Z' AND '2017-11-02T11:00:00Z'
AND S1.Status = 'ONLINE'
GROUP BY U1.id
LETTING S = MAX([S1.StatusChangedDate,S1])[1];
In 4.6.3+ you can also try this without UNNEST Using subquery expressions https://developer.couchbase.com/documentation/server/current/n1ql/n1ql-language-reference/subqueries.html . Array indexing query will be faster.
CREATE INDEX ix1 ON UserInformation(ARRAY v FOR v IN Statuses WHEN v.Status = 'ONLINE' END) WHERE type = "User";
SELECT U.Name, U.Gender, S.Status, S.StatusChangedDate
FROM UserInformation U1
LET S = (SELECT RAW MAX([S1.StatusChangedDate,S1])[1]
FROM U1.Statuses AS S1
WHERE S1.StatusChangedDate BETWEEN '2017-11-02T08:00:00Z' AND '2017-11-02T11:00:00Z' AND S1.Status = 'ONLINE')[0]
WHERE U1.type = 'User'
AND ANY v IN U1.Statuses SATISFIES
v.StatusChangedDate BETWEEN '2017-11-02T08:00:00Z' AND '2017-11-02T11:00:00Z' AND v.Status = 'ONLINE' END;
I'm new to SQL, please Help me how to convert this query into LinQ
This is My Table Dept:
Id Name Sal Department
1 John 40000 Dotnet
2 mick 45000 DotNet
3 Pillay 777 Sql
Here I want to display Salary Based On Department Name, like:
DepartmentName ToalSal
Dotnet 85000
Sql 777
select DeprtmentName,sum(sal) from Dept_Emp Group by DeprtmentName
I wrote some Part of query
public IEnumerable<Dept_Emp> GetJam()
{
var x = from n in db.Dept_Emp
group n by n.Sal into g
select new
{
DeprtmentName = g.Key
};
// what I mention Here;
}
You are missing calculating sum of sal fields of grouped entities. Also you are grouping by wrong field. You should use department name for grouping
from de in db.Dept_Emp
group de by de.DeprtmentName into g
select new {
DepartmentName = g.Key,
TotalSalary = g.Sum(x => x.Sal) // aggregation here
}
What you have as output is anonymous objects. You cannot return them directly from method. You have several options here
Create custom class like DepartmentTotals with name and total salary fields, and return instances of this class instead of anonymous objects. Then return type will be IEnumerable<DepartmentTotals>.
Create Tuple<string, int> (or whatever type of salary). And return such tuples.
Use C# 7 tuples.
I have some tables like "Job" "AppliedJob" "JobOffer" "Contract" "Employeer"
Description: When employeer post job it is stored in "Job" table with his ID. If a freelancer apply to the job it is stored in "AppliedJob" table with his ID. Then Employeer sees the application and send offer to the freelancer and it is stored in "JobOffer" table. If freelancer accept the offer it is then stored in "Contract" table. At first in "Contract" ContractID, OfferID and StratDate are stored and CompletedDate is stored as null. When the contract is completed the CompletedDate field is modified with date.
Want: I want to return all jobs with no completed contract
I tried:
[HttpGet]
[Route("api/PrivateApi/GetEmployeerPostedJob/")]
public object GetEmployeerPostedJob(int id)
{
var data = (from j in db.Jobs
where j.EmployeerID == id
join apl in db.AppliedJobs
on j.JobID equals apl.JobID
join o in db.JobOffers
on apl.AppliedJobID equals o.AppliedJobID
join con in db.Contracts
on o.OfferID equals con.OfferID
where con.CompletedDate == null
select new
{
j.JobTitle,
j.JobID,
j.Budget,
j.Deadline,
j.Employeer,
j.JobDetails,
j.PublishDate,
j.ReqSkill,
j.NoOFFreelancer,
j.Preference,
Category1=j.Category,
totalAppliedFreelancer=(from aple in db.AppliedJobs where j.JobID ==aple.JobID select aple).Count(),
Category = (from gg in db.Categories where gg.CategoryID == j.Category select gg.CategoryName).FirstOrDefault()
}).ToList();
return data.AsEnumerable();
}
But it returns no jobs.
How can i get all jobs which are not completed yet(CompletedDate == null in Contract table)?
I want to show the employeer's posted jobs on his page but only those jobs that are not completed
The above (die to one to many relationships involved) can be paraphrased as
return all jobs with no completed contract
while the way you wrote the query, besides the possible data duplication, it answers the question
return all jobs with existing, but not completed contract
i.e. is missing the jobs w/o applied job, applied job w/o offer and offer w/o contract.
The correct query would be something like this:
from job in db.Jobs
where job.EmployeerID == id
join jobContract in (
from appliedJob in db.AppliedJobs
join offer in db.JobOffers on appliedJob.AppliedJobID equals offer.AppliedJobID
join contract in db.Contracts on offer.OfferID equals contract.OfferID
select new { appliedJob, offer, contract }
) on job.JobID equals jobContract.appliedJob.JobID into jobContracts
where !jobContracts.Any(jobContract => jobContract.contract.CompletedDate != null)
select ...
The query could further be simplified by using navigation properties, but since I don't see navigation properties between AppliedJob and JobOffer, I'm leaving that for you.
Update: Here is the same query with navigation properties (by simplified I meant no need for join operators):
from job in db.Jobs
let completedContracts =
from appliedJob in job.AppliedJobs
from offer in appliedJob.JobOffers
from contract in offer.Contracts
where contract.CompletedDate != null
select contract
where !completedContracts.Any()
select ...
This LINQ query doesn't work on live server (sql-2008) But works on my local VS 2013. Is there any mistake if my live database is empty at first time?
#Ivan Stoev
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();
}
Can anyone show me, what i'm doing wrong?
I using c_id from company to give checkbox a value for later use.
I using name from company to write the name of the company next to the checkbox.
I using c_id from artistscompany to print "checked" in the checkboxes, where c_id from artistscompany are equal to c_id from artists.
$slsql = 'SELECT * FROM artistscompany WHERE a_id='.$ad_id;
$blsql = 'SELECT c_id, name FROM company WHERE c_id > 1';
if (($bl_result = mysqli_query($dbh, $blsql))AND($sl_result = mysqli_query($dbh, $slsql))) {
while($bl_row = mysqli_fetch_assoc($bl_result)){
$sl_raekke = mysqli_fetch_assoc($sl_result);
foreach((array)$sl_raekke as $sl_row){}
echo '<input type="checkbox" name="belongs[]" value="'.$bl_row['c_id'].'"'; if($sl_row == $bl_row['c_id']){echo'checked';}ELSE{echo'';} echo'> '.$bl_row['name'].'<br />';
}
mysqli_free_result($bl_result);
mysqli_free_result($sl_result);
}
$query = 'SELECT * FROM artistscompany a, company c WHERE c.c_id > 1 AND
c.c_id=a.c_id AND a_id='.$ad_id;
Now use this query to fetch and display from db.
a and c are used to refer to the fields. You want the c_id > 1 from company table, a_id=$variable and the same company ID in both tables. Correct me if I am wrong.