Entity Framework query with grouping (many to many) - linq-to-sql

I have a classical many to many scenario with three tables (students, courses, and third StudentsCourses assignment table).
I'm using EF in my new project and EF designer doesn't create third table.
I need to select all cources along with number of students assigned to it.
Using plain SQL is very straightforward:
select c.Id, c.Name, Count(sc.*) as StudentCount
from Courses c left join StudentCourses sc on(c.Id=sc.CourseId)
group by c.Id, c.Name
But I can't figure out how to translate this query to Linq to SQL.
Please advice.
Thank you.

The EF designer hides the table. It's still there, but it just creates the assocation for you, so you can just reference students from courses or vice versa.

You could do something like this:
var list = from c in context.Courses
from s in c.Students
select new
{
StudentName=s.Name,
Class=s.Class,
};
for more information look at this page

Related

MYSQL Search returning wrong and duplicate values

I'm doing a project at university and I seem to be encountering some issues when i'm trying to search to collect some results.
I am trying to display the results which give the StudentName, ModuleName, and DegreeID. When I do this, it appears to be duplicating the values and returning wrong results.
For example - Owen Barnes is only studying Computer Science, not Philosophy yet it is simply returning all values instead of the specified 3 it should. Further, Connor Borne is studying Philosophy yet it is suggesting he is studying every module including those in Computer Science.
I was hoping someone could help me. I'm using 2 tables (ModulesFormDegree & StudiesModules) which are used to link Modules to Degree (using 2 foreign keys) and Students with Modules (also using 2 foreign keys).
I've attached my problem below, if any more data is required please let me know.
Inquiry & Results
Description of Tables
Query:
select StudentName, ModuleName, DegreeID
from Student, Modules, Degree, StudiesModules, ModulesFormDegree
where Student.StudentID=StudiesModules.StudentID and
Modules.ModuleID=ModulesFormDegree.ModID and
Degree.DegreeID=ModulesFormDegree.DegID
It's diffcult to say for sure because you have not posted all your table definitions but your query is missing a condition in the where clause which is causing the Cartesian product and can be fixed as follows:
select StudentName,
ModuleName,
DegreeID
from Student,
Modules,
Degree,
StudiesModules,
ModulesFormDegree
where Student.StudentID=StudiesModules.StudentID and
Modules.ModuleID=ModulesFormDegree.ModID and
Degree.DegreeID=ModulesFormDegree.DegID and
StudiesModules.ModuleID = ModulesFormDegree.ModID
however, joining tables on conditions in the WHERE clause is fairly antiquated and superseded using ANSI joins as follows:
SELECT StudentName,
ModuleName,
DegreeID
FROM StudiesModules sm
JOIN ModulesFormDegree md
ON sm.ModuleID = md.ModID
JOIN Degree d
On d.DegreeID = md.DegID
JOIN Modules m
ON m.ModuleID = md.ModID
JOIN Student s
ON s.StudentID = sm.StudentID

Referencing one field for two different sets of related IDs in MySQL

I'm working on a school assignment for Databases and I'm running into a lot of trouble getting this one to work.
I'm trying to make a query for two columns, one of course prerequisites and one
for course IDs. The title in both of these columns must relate to the ID it is CONCATed with, which is only located under uni_course.
Here's what my output looks like right now from the following query (and what it should look like) :
SELECT CONCAT(uni_course.course_id,': ',title) as Course,
CONCAT(uni_prereq.prereq_id,': ',title) as Prerequisite
FROM uni_course
INNER JOIN uni_prereq ON uni_course.course_id = uni_prereq.course_id;
Any advice is very appreciated, thank you!
You need to add a join on the table again to get the description of the prerequisite course, hope that will help.
SELECT CONCAT(c.course_id,': ',c.title) AS Course,
CONCAT(p.prereq_id,': ',pc.title) AS Prerequisite
FROM uni_course AS c
INNER JOIN uni_prereq AS p ON c.course_id = p.course_id
INNER JOIN uni_course AS pc ON p.prereq_id = pc.course_id;

Query to Pull Data from 2 Junction Tables

I'm creating a database for comics. Right now I have 3 main tables (comics, publishers, people) and 3 junction tables (person2comic, publisher2comic and person2publisher). I want to be able to have a search form that allows searching by any combination of title, issue number, publisher, and person. When referencing only one junction table, I use a variation of this depending on what's being searched for:
SELECT comicTitle, comicIssue, firstName, lastName
FROM person2comic
JOIN comics ON comics.comicID = person2comic.comicID
AND comics.comictitle LIKE "%walk%" ;
If someone were to search by title, publisher and person, I'm not sure how to set up the statement since it would require using two of the junction tables. Would it be a nested query situation or something else?
You can have arbitrarily many joins. Not exactly sure on all of your column names, but this should roughly work:
SELECT *
FROM people
JOIN person2comic p2c ON people.id = ptc.person
JOIN comic ON p2c.comic = comic.id
JOIN publisher2comic pub2c ON comic.id = pub2c.comic
JOIN publisher ON pub2c.publisher = publisher.id
Also note that your schema may be inefficient if you relationships all aren't many-to-many. See my comment.

SQL to retrieve related records with many to many relation

I am building an application for registration of agreements between institutes. These agreements may include more than 2 partners. As such, I quickly dropped the idea of having part1 and partner2 in a contracts table.
Current design is (Note: simplified for question):
Table Institutes: ID, Name , ..
Table Contract_institutes: ContractID, InstituteID
Table Contracts: ID, Title, ...
How would I go about showing a list of all contracts including the involved partners, assuming you know one partner: A user is logged in, and wants to see all the contracts that his institute has, and all the partners in the contract; e.g.:
Contract1: (Title) Institute1Name, Institute2Name
Contract2: (Title) Institute1Name, Institute2Name, Institute3Name
Contract3: (Title) Institute1Name
I could first get all the contracts IDs
select *fields*
from Contracts
left join Contract_institutes on Contracts.ID = Contract_institutes.ContractID
where Contract_institutes.InstituteID = *SomeValue*
And then get all the related institutes with a separate query for each contract (Or using an IN statement in the query), and use a lot of foreach php loops to format. Not pretty, and probably not efficient.
There must be a better way to do this, and get the list in a single sql statement. Can someone help me?
Ideally, I get output rows with: [contract ID][InstituteID][Institute.Name]. I can easily modify this in a per-contract view in the output.
PS:
- This is design phase of the application: The database is empty and can be modified to needs.
select C.ID, I.ID, I.Name
from Contracts C
join Contract_institutes CI on C.ID = CI.ContractID
join Institutes I on I.ID=CI.InstituteId
where CI.InstituteID <> *SomeValue*
and CI.ContractID in (select CI2.ContractId
from Contract_institutes CI2
where CI2.InstituteID = *SomeValue*)

MySQL design issue

I think the design is straightforward so no explanation is required.
Question: Is there a way to inditcate the language of the name column in courses table? Maybe to link it with the languages table?
Edit: Or maybe separate the name-language pare in another table with id and reference it in courses table?
Edit2: Course language and Name langauge may be different
Question: Is there a way to inditcate the language of the name column in courses table? Maybe to link it with the languages table?
There's no need. The following query will give you what you want:
SELECT c.name, COALESCE(l.name,'default') as language
FROM courses c
LEFT JOIN courses_has_languages cl ON (cl.courses_course_id = c.course_id)
LEFT JOIN languages l ON (l.language_id = cl.languages_language_id)
Of source it would be even better if you just rename your column names so the query can be rewritten to:
SELECT c.name, COALESCE(l.name,'default') as language
FROM courses c
LEFT JOIN courses_has_languages cl ON (cl.course_id = c.id)
LEFT JOIN languages l ON (l.id = cl.language_id)
But that's just my preference.
If I understand you it sounds like you're on the right track.
Make language_id a foreign key in the courses table that points back to languages.
Assuming that the diagram correctly models the data then no, you do not need any additional relationships.
Instead, you will retrieve the languages for a course by JOINing the tables in a SELECT statement. If this is an operation you will perform frequently, you can encapsulate that SELECT statement by CREATEing a VIEW.