SQL: Count rows which are not present in table - c#

I got two tables called: EmployeeTable & TaskAssignmentTable.
They look like this :
TaskAssignmentTable shows tasks assigned to employees. In order to assign new tasks to employees i want to have count of tasks assigned to different people and then assign task to people who have least tasks assigned.
Problem: using normal count() on TaskAssignmentTable results in this table:
But what i want is some sort of join between tables which shows count of rows which are present in first table and absent in 2nd table with count equal to 0 like this one:
So what would be the SQL query to join tables and do such thing? (Optional: Since I'm using C# Linq-2-SQL i would be grateful if someone can write LINQ syntax for this).

You need a LEFT OUTER JOIN based upon your statement that you want rows that are present in the first table but not the second:
SELECT EmployeeID, Name, Count(TaskID) as CNT
FROM EmployeeTable e
LEFT JOIN TaskAssignmentTable t
ON e.employeeID = t.FKEmployeeID
GROUP BY EmployeeID, Name

Try
SELECT EmployeeID, Name, Count(TaskID) as CNT
FROM EmployeeTable emp
LEFT JOIN TaskAssignmentTable task on emp.employeeID = task.FKEmployeeID
GROUP BY EmployeeID, Name

For that you have to use Left Outer Join.
SELECT EmployeeID, Name, Count(TaskID) as CNT
FROM EmployeeTable emp
LEFT OUTER JOIN TaskAssignmentTable task on emp.employeeID = task.FKEmployeeID
GROUP BY EmployeeID, Name
And LINQ Version of this query look like this
var employees = from emp in dbContext.Employees
join task in dbContext.TaskAssignmentTable
on emp.employeeID equals task.FKEmployeeID
into tEmpWithTask
from tEmp in tEmpWithTask.DefaultIfEmpty()
group tEmp by new { emp.EmployeeID, emp.Name } into grp
select new {
grp.Key.EmployeeID,
grp.Key.Name,
grp.Count(t=>t.TaskID != null)
};

You need to OUTER JOIN the two table (in your case a LEFT JOIN):
SELECT EmployeeID, Name, Count(TaskID) as CNT
FROM EmployeeTable emp
LEFT JOIN TaskAssignmentTable task on emp.employeeID = task.FKEmployeeID
GROUP BY EmployeeID, Name

Related

How can I turn SQL query that joins two columns and groups by count of one column and a column of each joined table into LINQ?

In my database, each URI has associated tags (Tag table) and each pageview (PageView table) is associated with someone viewing a particular page. I want to return a list of URIs that have the same tags as a given URI, by count of each URI that shares those tag(s). My SQL query looks like this:
select count(URI) as 'Count', p.URI, t.Name
from tracking.PageView as p
inner join Tracking.Tag as t on p.ID = t.PageViewID
where t.name in
(select t.Name
from tracking.PageView as p
inner join Tracking.Tag as t on p.ID = t.PageViewID
where p.URI = 'URI WE WANT TAGS OF'
)
and p.uri like '%/articles/%'
group by p.URI , t.name
order by Count desc
My apologies if the description is too vague for the query or if the query itself is rough. It was just the first one that worked. I've tried to separate the subquery into a variable and select values in that subquery, but it's been some time since I've used LINQ and I'm spinning wheels at this point.
The following is pretty much an exact translation of your current SQL query, which should get you started.
from p in tracking.PageView
join t in Tracking.Tag on p.ID equals t.PageViewID
where p.uri.Contains("/articles/")
&& (
from p2 in tracking.PageView
join t2 in Tracking.Tag on p2.ID equals t2.PageViewID
where p2.URI == "URI WE WANT TAGS OF"
select t2.name
).Contains(t.name)
group new { p, t } by new { p.URI, t.name } into g
orderby g.Count() descending
select new {
Count = g.Count(),
g.Key.URI,
g.Key.Name
}

Linq Query - Using select, group by, joins, functions, and order by at once?

I have a fairly complex query that I'm trying to implement via Linq. I'm struggling to find a way to:
Order by a select return (the IFNULL result that's selected is used in the group by)
Get all the distinct results a group by in sql would
How can I reproduce this query via Linq?
select
company.id
IFNULL(employee.team_name, employee.name) AS team_name
FROM company
INNER JOIN branch on branch.parent_company_id = company.uuid
INNER JOIN map_employee_to_branch on map_employee_to_branch.machine_uuid = branch.uuid
INNER JOIN employee on employee.id = map_employee_to_branch.employee_id
where company.name = "Whatever" AND map_employee_to_branch.isActive = true
GROUP BY map_employee_to_branch.employee_id, company.id
ORDER BY company.id, employee.title, team_name, employee.name
I'm going to assume your inner joins are handled by your navigation property mappings, and I'm making some assumptions about your entity property names.
(from company in context.Companies
where company.name = "Whatever"
from branch in company.Branches
from m in branch.MapEmployeeToBranches
where m.IsActive
let employee = m.Employee
select new {
companyId = company.id,
employeeId = employee.id
employee.title,
teamName = employee.team_name ?? employee.name,
employee.name
} into projection
orderby projection.id, projection.title, projection.teamName, projection.name
group new { projection.companyId, projection.teamName }
by new { projection.employeeId, projection.companyId }

How to use group by on an outer join in linq to SQL

Please i have my two tables, i recently learnt to outer join the two in linq. My problem now is i want to use group by a particular column for a i want to return a sum as well. Below is how i join the tables.
var result = from l1 in repository.Locations
join l2 in repository.Rooms on l1.LocationName equals l2.Location
into l3
from tempLocations in l3.DefaultIfEmpty()
select new
{
l1.LocationName,
total = (tempLocations == null ? String.Empty : tempLocations.Location)
};
My problem is the column total, intend to group by l1.LocationName and the count() as total. Please any help would be appreciated.
UPDATE
I want to group by the Location Column and LocationName column from the l1 and l2 tables. I want to return something like.
The LocationNAme is from Locations Table , LOcation Column is from Rooms Table , i want to outer join the two tables where LocationNAme = Location and count existence of LocationName in Room Table .

LEFT Join not returning records in MS Access

My recent project I have a requirements to print receivable summary. I need to return entire rows from the OpeningBalance table and matching rows from VoucherHeader and Customers.
My SQL query is this
SELECT
OpeningBalance.OpenID, Sum(OpeningBalance.Amount) AS SumOfAmount,
Sum(VoucherHeader.Debit) AS SumOfDebit, Sum(VoucherHeader.Credit) AS SumOfCredit,
Customers.CustomerID, Customers.CustomerName
FROM
(OpeningBalance
LEFT OUTER JOIN
VoucherHeader ON OpeningBalance.OpenID = VoucherHeader.LedgerID)
INNER JOIN
Customers ON OpeningBalance.OpenID = Customers.CustomerID
WHERE
(((Customers.CustomerType)='Debtor')
AND ((VoucherHeader.VoucherDate)<#2013/06/02#))
GROUP BY
OpeningBalance.OpenID, Customers.CustomerID, Customers.CustomerName,
VoucherHeader.LedgerID
ORDER BY
Customers.CustomerName;
Please help.
SELECT OB.OpenID, Sum(OB.Amount) AS SumOfAmount,
Sum(VB.Debit) AS SumOfDebit, Sum(VB.Credit) AS SumOfCredit, CS.CustomerID,
CS.CustomerName FROM OpeningBalance OB
LEFT OUTER JOIN VoucherHeader VB ON OB.OpenID = VB.LedgerID
LEFT OUTER JOIN Customers CS ON OB.OpenID = CS.CustomerID
WHERE (((CS.CustomerType)='Debtor') AND ((VB.VoucherDate)<#2013/06/02#))
GROUP BY OB.OpenID, CS.CustomerID, CS.CustomerName, VB.LedgerID
ORDER BY CS.CustomerName;

NHibernate Native SQL multiple joins

I"m having some problems with Nhibernate and native sql.
I've got an entity with alot of collections and I am doing an SQL Fulltext search on it. So when returning 100 or so entities, I dont want all collections be lazy loaded. For this I changed my SQL query:
SELECT Query.*
FROM (SELECT {spr.*},
{adr.*},
{adrt.*},
{cty.*},
{com.*},
{comt.*},
spft.[Rank] AS [Rak],
Row_number() OVER(ORDER BY spft.[Rank] DESC) AS rownum
FROM customer spr
INNER JOIN CONTAINSTABLE ( customerfulltext , computedfulltextindex , '" + parsedSearchTerm + #"' ) AS spft
ON spr.customerid = spft.[Key]
LEFT JOIN [Address] adr
ON adr.customerid = spr.customerid
INNER JOIN [AddressType] adrt
ON adrt.addresstypeid = adr.addresstypeid
INNER JOIN [City] cty
ON cty.cityid = adr.cityid
LEFT JOIN [Communication] com
ON com.customerid = spr.customerid
INNER JOIN [CommunicationType] comt
ON comt.communicationtypeid = com.communicationtypeid) as Query
ORDER BY Query.[Rank] DESC
This is how I setup the query:
var items = GetCurrentSession()
.CreateSQLQuery(query)
.AddEntity("spr", typeof(Customer))
.AddJoin("adr", "spr.addresses")
.AddJoin("adrt", "adr.Type")
.AddJoin("cty", "adr.City")
.AddJoin("com", "spr.communicationItems")
.AddJoin("comt", "com.Type")
.List<Customer>();
What happens now is, that the query returns customers twice (or more), I assume this is because of the joins since for each customer address, communicationItem (e.g. phone, email), a new sql row is returned. In this case I thought I could use the DistinctRootEntityResultTransformer.
var items = GetCurrentSession()
.CreateSQLQuery(query)
.AddEntity("spr", typeof(Customer))
.AddJoin("adr", "spr.addresses")
.AddJoin("adrt", "adr.Type")
.AddJoin("cty", "adr.City")
.AddJoin("com", "spr.communicationItems")
.AddJoin("comt", "com.Type")
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<Customer>();
Doing so an exception is thrown. This is because I try to list customers .List<Customer>() but the transformer returns only entities of the last join added. E.g. in the case above, the entity with alias "comt" is returned when doing .List() instead of .List<Customer>(). If I would switch last join with the join alias "cty", then the transformer returns a list of cities only...
Anyone knows how I can return a clean list of customers in this case?
try this
var items = GetCurrentSession()
.CreateSQLQuery(query)
.AddEntity("spr", typeof(Customer))
.AddJoin("adr", "spr.addresses")
.AddJoin("adrt", "adr.Type")
.AddJoin("cty", "adr.City")
.AddJoin("com", "spr.communicationItems")
.AddJoin("comt", "com.Type")
.AddEntity("spr", typeof(Customer))
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<Customer>();
GetCurrentSession.CreateQuery("select distinct spr from Customer spr inner join spr.Addresses
adr inner join adr.Type adrt inner join adr.City cty inner join apr.CommunicationItems com
inner join com.Type comt").List<Customer>();
Hope this helps. Or you can write the desired SQL query under
GetCurrentSession.CreateSqlQuery(sqlquery).List<Customer>();

Categories

Resources