GroupBy LINQ to SQL not working, perhaps - linq-to-sql

I'm struggling to get groupby working in LINQ to SQL, im pretty new to it...I trying to groupby g.id but it just wont work...any help would be greatly appreciated...Cheers
IQueryable<GuestList> query = from t in _ttx.Trips
join l in _ttx.Legs on t.Id equals l.TripId
join gl in _ttx.GuestLegs on l.Id equals gl.LegId
join g in _ttx.Guests on gl.GuestId equals g.Id
where t.Id == id
select new GuestList()
{
Id = g.Id,
Name = g.Name,
NoOfLegs = g.GuestLegs.Count()
};
My result is
1 paul 3
2 Jim 1
1 paul 3
1 paul 3

Please try is as below.
var query2 = (from ps in query
group ps by new { ps.Id } into prod
select new GuestList
{
Id = prod.Key.Id,
Name = prod.Name,
NoOfLegs = prod.Sum(c => c.NoOfLegs),
}).OrderBy(x => x.Id).ToList();

Related

SQL Left Join Query to match all restriction from result

I´m trying to filter data with some categories where i get a result matching all given slug / type parameteres.
Currently i got stuck with extendending my current query to get the data with a single query. My current query looks like that:
SELECT t.slug, tc.t_id, tc.c_id
FROM tc
LEFT JOIN t ON t.id = tc.t_id
WHERE
(t.type = 'offerAges' AND t.slug = '14-16')
OR
(t.type = 'offerSportTypes' AND t.slug = 'football')
Gives me following result:
# slug t_id c_id
1 football 13 40
2 14-16 28 39
3 14-16 28 40
The result i want is that i just get the results where t_id AND c_id are matching. For example in my table the items 1 & 3.
Fiddle: https://www.db-fiddle.com/f/vQUU9C9iXj4gotE7YGDq6W/1
You can use aggregation. In this case:
SELECT tc.c_id
FROM tc JOIN
t
ON t.id = tc.t_id
WHERE (t.type = 'offerAges' AND t.slug = '14-16') OR
(t.type = 'offerSportTypes' AND t.slug = 'football')
GROUP BY tc.c_id
HAVING COUNT(DISTINCT t.type) = 2;
If you want the slugs, I would recommend using GROUP_CONCAT() to put them in a single column:
GROUP_CONCAT(t.slug)

A mySQL query to check one option, and if not true, another option?

I am very new at mySQL.
I am doing a lookup of certain records from a table and the requirements have now changed. At first the query would pull the name of the person who was marked as the captain on the job plus a few other conditions. Now my boss wants me to pull the transcriber on the job if there is no captain. How can I do this in mySQL?
My code is:
$Q = $this->read_db->query('
select DISTINCT j.id, j.reference, max(ja.FinalDue) as FinalDue, j.clientdue, j.pagecount, t.name, ja.iscaptain
from `job` j
join `jobattachment` a on a.`jobid` = j.`id`
join `jobassignment` ja on a.`jobid` = ja.`jobid`
join `transcriber` t on ja.`transcriberid` = t.`id`
where ja.`iscaptain` = 1
and ja.`deleted` != 1
and (a.`editing` = 2 or a.`editing` = 3)
and a.`redline` != 0
and j.`complete` = 0
group by j.id');
return $Q->result_array();
How can I make the query find the captain, and only if there is no captain, find the person whose ID is in the redline field? The jobattachment table has multiple records for each job and if the attachment is marked as a redline, the transcriber's ID would be in that field, otherwise it would be empty.
I tried changing the query by adding an or, but I don't want the captain or the transcriber, only the transcriber if there is no captain. Any help would be much appreciated.
I played around with this a lot and this is the solution I have come up with. Thank you to everyone that responded.
public function getRedlinesNotCompleted() {
$Q = $this->read_db->query('
select j.id, j.reference, max(ja.FinalDue) as FinalDue, j.clientdue, j.pagecount, t.name, max(ja.iscaptain) as iscaptain
from `job` j
join `jobattachment` a on a.`jobid` = j.`id`
join `jobassignment` ja on a.`jobid` = ja.`jobid`
join `transcriber` t on ja.`transcriberid` = t.`id`
where ja.`deleted` != 1
and (a.`editing` = 2 or a.`editing` = 3)
and a.`redline` != 0
and j.`complete` = 0
group by j.id');
return $Q->result_array();
}
public function getCaptainNameForRedlineJobsNotCompleted($jobid) {
$Q = $this->read_db->query('
SELECT t.name, max(j.iscaptain) as iscaptain
FROM jobassignment j
JOIN transcriber t ON t.id = j.transcriberid
WHERE j.jobid = ' . $jobid . ' AND j.iscaptain = 1');
return $Q->row()->name;
}
select DISTINCT j.id, j.reference, max(ja.FinalDue) as FinalDue, j.clientdue, j.pagecount, case when ja.iscaptain then t.name else (select name from t where id = a.redline) end , ja.iscaptain
from `job` j
join `jobattachment` a on a.`jobid` = j.`id`
join `jobassignment` ja on a.`jobid` = ja.`jobid`
join `transcriber` t on ja.`transcriberid` = t.`id`
where
and ja.`deleted` != 1
and (a.`editing` = 2 or a.`editing` = 3)
and a.`redline` != 0
and j.`complete` = 0
group by j.id'
Explanation:
First remove the ja.iscaptain = 1 part from the where clause so you can get all the people that also not captains.
Second, the t.name is changed according to the person if he is a captain or not, so instead of returning it hardcoded, you should check if its a captain then its name is t.name, else get the name from transcriber table by a.redline id.
I hope that I understood it correctly and it helps :)

i'm using 2 queries is there any way to make it single query

here is my situation,
i'm obtaining id from superadmin table where role=2
like this
SELECT id FROM superadmin WHERE role='2'
suppose i will get 10 records
id
----------------
3
4
6
8
10
14
16
.
.
i need to pass them into 2nd table like this
SELECT status FROM categorydata WHERE users='id' // above id on each iteration
here is my code in PHP:
$query_super_admin = $obj->queryAll("SELECT id FROM superadmin WHERE role='2'");
foreach($query_super_admin['results'] as $result){
$user_id = $result['id'];
$category_related = $obj->queryAll("SELECT status FROM categorydata WHERE users='".$user_id."'");
// result data
}
QUESTION: i want to achieve this with sql is this possible?
TRY THIS : I think INNER JOIN will perform better in this case
SELECT c.status
from superadmin s
inner join categorydata c on s.id = c.users
where s.role='2'
The following query will retrieve users along with their statuses:
SELECT s.id, c.status
FROM superadmin s
LEFT JOIN categorydata c ON s.id = c.users
WHERE s.role = 2
ORDER BY s.id;
I use a LEFT JOIN instead of an INNER JOIN like Suraz because you may be interested in getting users with no status associated.
Then in PHP, to get the same behavior as your initial code, you can do as follows:
$query = <<<EOQ
SELECT s.id, c.status
FROM superadmin s
LEFT JOIN categorydata c ON s.id = c.users
WHERE s.role = 2
ORDER BY s.id;
EOQ;
$query_super_admin = $obj->queryAll($query);
$cur_id = -1;
foreach($query_super_admin['results'] as $result) {
if ($result['id'] != $cur_id) {
// This is a new user id
// Do whatever you want here, like printing user id, name, etc.
$cur_id = $result['id'];
}
if (!$result['status']) {
continue; // No status associated to this user
}
// Do whatever you want here, like printing status
}
You can use WHERE IN (...):
SELECT status
FROM categorydata
WHERE users IN (SELECT id FROM superadmin WHERE role = '2')

LINQ Query with join, group by and Sum()

I've working on this for a while so I thought I'd post here to see if anyone has any idea how a query like the following can be converted to LINQ.
Here is the MySQL Query:
SELECT SUM(line_ord.itemqty) AS LineOrderQTY, SUM(assemblyNumber.qty) AS
AssemblyQTY FROM line_ord
LEFT JOIN
(
SELECT sum(assemblyno.qty) AS qty, assemblyno.row_id FROM assemblyno
INNER JOIN line_ord ON assemblyno.row_id = line_ord.row_id
WHERE line_ord.bdnum = 'S61460'
) AS assemblyNumber ON line_ord.row_id = assemblyNumber.row_id
WHERE line_ord.bdnum = 'S61460'
This what I have so far for the LINQ query, but it doesn't return the proper results.
var items = (from c in Context.OrderLineItemData
join e in Context.AssemblyLabelData on c.ID equals e.RowID
where c.BreakdownNumber == breakdownNumber
group c by c.BreakdownNumber into g
select new
{
AssemblyQuantity= g.Sum(x => x.Quantity),
LineOrdQuantity = g.Sum(**WHAT GOES HERE?**)
}).FirstOrDefault()
I did manage to get it to work like this, but it seems kind of messy to me.
var items = (from c in Context.OrderLineItemData
join e in Context.AssemblyLabelData on c.ID equals e.RowID
where c.BreakdownNumber == breakdownNumber
group c by c into g
select new
{
AssemblyQuantity= g.Sum(x => x.Quantity),
LineOrdQuantity = (from e in Context.OrderLineItemData where e.BreakdownNumber == breakdownNumber select e.Quantity).Sum()
}).FirstOrDefault();
Is there a better way to do this?
Got my answer. Seems like a query object has to be created and then I can use it to preform my calculations.
var items = (from od in Context.OrderLineItemData
join ad in Context.AssemblyLabelData on od.ID equals ad.RowID into odGroup
from g in odGroup.DefaultIfEmpty()
where od.BreakdownNumber == breakdownNumber
group g by new
{
breakdown = od.BreakdownNumber,
LineOrd = od,
AssemblyQty = g == null ? 0 : g.Quantity
}
into groupped
select new
{
Breakdown = groupped.Key.breakdown,
AssemblyQty = groupped.Sum(x => x.Quantity),
lineOrdQty = groupped.Key.LineOrd.Quantity
}
);
int remainingQuantity = items.Sum(x => x.lineOrdQty) - items.Sum(x => x.AssemblyQty);

query is not working correctly

I have these tables:
single_user_has_university_has_course
single_user_users_id_user university_has_course_university_id_university university_has_course_course_id_course first_year_school last_year_school grade
1 1 1 2000 2001 15
And
university_has_course
university_id_university course_id_course
1 1 <<< I want to select this
15 1
1 3
15 3
The problem is that the query below return all rows where course_id_course = 1 but ignore theuniversity_id_university = 1`. Then, will return two rows.
query:
SELECT A.first_year_school, A.last_year_school, A.grade, U.university, C.course, T.type_course
FROM single_user_has_university_has_course A
INNER JOIN university_has_course Q
ON A.university_has_course_course_id_course = Q.course_id_course
INNER JOIN university U
ON Q.university_id_university = U.id_university
INNER JOIN course C
ON Q.course_id_course = C.id_course
INNER JOIN type_course T
ON C.type_course_id_type_course = T.id_type_course
AND A.single_user_users_id_user = ?
You are joining the last table to the previous joins on 2 constraints C.type_course_id_type_course = T.id_type_course AND A.single_user_users_id_user = ?. I think you want to write it as a WHERE clause. So replace your last line with:
WHERE A.single_user_users_id_user = ?
But you're not also trying to filter university_id_university = 1, so you may want to add it to the WHERE clause as well:
WHERE A.single_user_users_id_user = ? AND Q.university_id_university = ?